pata
pata

Reputation: 989

FetchType.LAZY is not getting the objects from db

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

Answers (2)

pata
pata

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

kostja
kostja

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

Related Questions