Using Hibernate, there is a problem with lazy-loaded collections in detached objects. Consider this sequence of events. In one session, load an object with a lazy-loaded collection property. Close the session and open a new session. Associate the object with the new session. Access an element of the collection (e.g. myCollection.first()). The following exception occurs:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: MyEntity.myCollection, no session or session was closed at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358) at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350) at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343) at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86) at org.hibernate.collection.PersistentSortedSet.first(PersistentSortedSet.java:93)
A quick trip in the debugger shows that the session is closed. Apparently, attaching an entity to a session does not attach its lazy collection properties. So, how does one do that? Well, you could try Hibernate.initialize(myCollection). But then you would get:
org.hibernate.HibernateException: disconnected session
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:452)
at org.hibernate.Hibernate.initialize(Hibernate.java:309)
Perhaps mySession.lock(myCollection, LockMode.NONE)? Nope, this gives:
org.hibernate.MappingException: Unknown entity: org.hibernate.collection.PersistentSortedSet
at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:550)
at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1338)
at org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:50)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:584)
at org.hibernate.impl.SessionImpl.lock(SessionImpl.java:576)
Okay, surely this will work:
PersistentCollection collection = (PersistentCollection) myCollection;
collection.setCurrentSession((SessionImplementor) mySession);
Hibernate.initialize(myCollection);
Nope:
org.hibernate.HibernateException: collection was evicted
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:38)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:454)
at org.hibernate.Hibernate.initialize(Hibernate.java:309)
onInitializeCollection is calling PersistenceContext.getCollectionEntry(collection) and coming up empty -- the new session has no clue about the collection.
I'm stumped. I can't figure out how to bring an uninitialized collection into a new session. It looks like you must initialize a collection in the session that first accesses it.