2

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.

3
  • There is no reason for not allowing multiple eager element collections, are you sure the exception you get is about that? Commented Nov 14, 2012 at 14:26
  • 2
    You should be able to define and eagerly fetch multiple collections as long as the additional collections (beyond the first) have an @OrderColumn defined. Commented Nov 14, 2012 at 14:32
  • with the @orderClumn i was able to get the callections! FetchType.EAGER worked perfectly. Regards Perception Commented Nov 14, 2012 at 16:05

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

its throws the same exception :(
@GuillermoVarini if you are still getting the LazyInitializationException, this probably means that the companyToSynchronize is detached already. If em.contains(companyToSynchronize) returns false, you should either merge your entity or find it again.
3

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.