I have a service that gets a JPA entity from outside code. In this service I would like to iterate over a lazily loaded collection that is an attribute of this entity to see if the client has added something to it relative to the current version in the DB.
However, the client may have never touched the collection so it's still not initialized. This results in the well known
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.SomeEntity.
Of course, if the client never touched the collection, my service doesn't have to check it for possible changes. The thing is that I can't seem to find a way to test whether the collection is initialized or not. I guess I could call size()
on it and if it throws LazyInitializationException
I would know, but I'm trying not to depend on such patterns.
Is there some isInitialized()
method somewhere?
By default, JPA uses the lazy fetch strategy in associations of type @ElementCollection. Thus, any access to the collection in a closed Persistence Context will result in an exception. This test throws an exception when we try to access the phone list because the Persistence Context is closed.
Implementing a Lazy-Initialized Property To implement a public property by using lazy initialization, define the backing field of the property as a Lazy<T>, and return the Value property from the get accessor of the property. The Value property is read-only; therefore, the property that exposes it has no set accessor.
1. Working with lazy associations. By default, Hibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for most associations in the majority of applications.
With a LAZY type dependency, only data of the wanted object is loaded: author's data is not retrieved. With Spring Data JPA, every relationship between 2 domain objects owns one of these data loading types. By default, the method will be determined by the relationship type.
Are you using JPA2?
PersistenceUnitUtil
has two methods that can be used to determine the load state of an entity.
e.g. there is a bidirectional OneToMany/ManyToOne relationship between Organization and User.
public void test() { EntityManager em = entityManagerFactory.createEntityManager(); PersistenceUnitUtil unitUtil = em.getEntityManagerFactory().getPersistenceUnitUtil(); em.getTransaction().begin(); Organization org = em.find(Organization.class, 1); em.getTransaction().commit(); Assert.assertTrue(unitUtil.isLoaded(org)); // users is a field (Set of User) defined in Organization entity Assert.assertFalse(unitUtil.isLoaded(org, "users")); initializeCollection(org.getUsers()); Assert.assertTrue(unitUtil.isLoaded(org, "users")); for(User user : org.getUsers()) { Assert.assertTrue(unitUtil.isLoaded(user)); Assert.assertTrue(unitUtil.isLoaded(user.getOrganization())); } } private void initializeCollection(Collection<?> collection) { // works with Hibernate EM 3.6.1-SNAPSHOT if(collection == null) { return; } collection.iterator().hasNext(); }
org.hibernate.Hibernate.isInitialized(..)
There is no standard JPA solution to my knowledge. But if you want to actually initialize collections, you can create an utility method and iterate them (only one iteration is enough).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With