Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test whether lazy loaded JPA collection is initialized?

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?

like image 342
akira Avatar asked Nov 29 '10 17:11

akira


People also ask

How lazy loading works in JPA?

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.

How do you initialize a lazy?

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.

Is lazy loading default in hibernate?

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.

What is lazy loading in Spring JPA?

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.


2 Answers

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(); } 
like image 146
dira Avatar answered Oct 01 '22 14:10

dira


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).

like image 23
Bozho Avatar answered Oct 01 '22 14:10

Bozho