How to eagerly load lazy fields with JPA 2.0?

14,364

Solution 1

I'd try Hibernate.initialize(movie). But calling the getter (and adding a comment that this forces initialization) is not that wrong.

Solution 2

You can use the fetch all properties keywords in your query:

SELECT movie 
FROM Movie movie FETCH ALL PROPERTIES
WHERE ...

Solution 3

The one possible solution is:

SELECT movie 
FROM Movie movie LEFT JOIN FETCH movie.referencedEntities
WHERE...

Other could be to use @Transactional on method in ManagedBean or Stateless and try to access movie.getReferencedEntities().size() to load it but it will generate N+1 problem i.e. generating additional N queries for each relationship which isn't too efficient in many cases.

Solution 4

To quote the JPA spec (2.0, 11.1.6):

The LAZY strategy is a hint to the persistence provider runtime that data should be fetched lazily when it is first accessed. The implementation is permitted to eagerly fetch data for which the LAZY strategy hint has been specified.

Hibernate only supports what you are trying if you use its bytecode enhancement features. There are a few ways to do that. First is to use the build-time enhancement tool. The second is to use (class-)load-time enhancement. In Java EE environments you can enable that on Hibernate JPA using the 'hibernate.ejb.use_class_enhancer' setting (set it to true, false is the default). In Java SE environments, you need to enhance the classes as they are loaded, either on your own or you can leverage org.hibernate.bytecode.spi.InstrumentedClassLoader

Share:
14,364
Zhao Yi
Author by

Zhao Yi

Updated on June 11, 2022

Comments

  • Zhao Yi
    Zhao Yi almost 2 years

    I have an entity class that has a lazy field like this:

    @Entity
    public Movie implements Serializable {
        ...
        @Basic(fetch = FetchType.LAZY)
        private String story;
        ...
    }
    

    The story field should normally be loaded lazily because it's usually large. However sometimes, I need to load it eagerly, but I don't write something ugly like movie.getStory() to force the loading. For lazy relationship I know a fetch join can force a eager loading, but it doesn't work for lazy field. How do I write a query to eagerly load the story field?

  • Zhao Yi
    Zhao Yi over 12 years
    I'd like to use standard JPA API instead of Hibernate-specific one, because it's likely I'll use another JPA implementation next time. As to the getter, if the entity class has many lazy fields, I have to write many getters to force the loading, which is also what I'm expecting.
  • Bozho
    Bozho over 12 years
    well, I don't think there's a standard utility. There is isInitialized(..). but not initialize()
  • Michał Ziobro
    Michał Ziobro over 8 years
    It works only for @***ToOne relationships and not for @***ToMany relationships
  • Michał Ziobro
    Michał Ziobro over 8 years
    It causes N+1 problem
  • 30thh
    30thh over 8 years
    Yes it can, but there is unfortunately no better solution. The general advice is - "avoid the situation you need to load all the dependencies".
  • caraca
    caraca almost 4 years
    This is the perfect solution if you are querying with JPQL which is my case, thanks!