How to eagerly load lazy fields with JPA 2.0?
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
Zhao Yi
Updated on June 11, 2022Comments
-
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 over 12 yearsI'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 over 12 yearswell, I don't think there's a standard utility. There is
isInitialized(..)
. but not initialize() -
Michał Ziobro over 8 yearsIt works only for @***ToOne relationships and not for @***ToMany relationships
-
Michał Ziobro over 8 yearsIt causes N+1 problem
-
30thh over 8 yearsYes it can, but there is unfortunately no better solution. The general advice is - "avoid the situation you need to load all the dependencies".
-
caraca almost 4 yearsThis is the perfect solution if you are querying with JPQL which is my case, thanks!