Reputation: 989
Using JPA (EntityManager) and Hibernate.
I have a class with 3 collections, one it has FetchType.EAGER and the other two has LAZY. If i put the 3 of them in EAGER, i get an exception as it can only have one. On this way, when i try to use one of the LAZY list, i get an exception :
no session or session was closed: javax.faces.el.EvaluationException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:
So, how can i get the 2 collections when i ask for them?
My class:
public class Event implements....
....
....
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name="friendsList")
private List<Long> friends;
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name="carsList")
private List<Long> cars;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name="housesList")
private List<Long> houses;
i tried this but still not working
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public IEvent synchronizeCarsList(IEvent companyToSynchronize){
if(companyToSynchronize == null)
throw new IllegalArgumentException();
if(entityManager != null) {
List<Long> cars = companyToSynchronize.getSelectedCarsIdList();
}
return companyToSynchronize;
}
edit: Exception on deploy when i have more than one EAGER in one entity(or what i understand from the log)
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:94) [:3.6.6.Final]
at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:119) [:3.6.6.Final]
at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:71) [:3.6.6.Final]
at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:54) [:3.6.6.Final]
at org.hibernate.loader.entity.BatchingEntityLoader.createBatchingEntityLoader(BatchingEntityLoader.java:133) [:3.6.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:1914) [:3.6.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:1937) [:3.6.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.createLoaders(AbstractEntityPersister.java:3205) [:3.6.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.postInstantiate(AbstractEntityPersister.java:3191) [:3.6.6.Final]
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:348) [:3.6.6.Final]
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1872) [:3.6.6.Final]
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:906) [:3.6.6.Final]
... 105 more
Regards.
Upvotes: 2
Views: 4049
Reputation: 989
What i did was :
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name="friendsList")
@OrderColumn(insertable=true,updatable=true,name="friendsOrder")
private List<Long> friends;
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name="carsList")
@OrderColumn(insertable=true,updatable=true,name="carsOrder")
private List<Long> cars;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name="housesList")
private List<Long> houses;
On this way, i get all the collections at once. I have to read more about @OrderColumn but in this case it worked for me. Thx to @Perception.
Upvotes: 3
Reputation: 61538
Simply assigning the value of the lazily loaded Collection
is not enough to trigger the loading. All you will get is a reference to a proxy. That's why an access outside the transaction will fail.
Calling .size()
on the Collection
, while still in the transaction, will trigger the loading, as will any other method requiring access to the actual contents.
Upvotes: 3