CLONE - One-to-Many relationship not working with custom Loader
Description
Within the context of a One-to-Many relationship, NamedQueryCollectionInitializer .initialize() never actually populates the PersistantBag on the parent after it calls query.setCollectionKey( key ).setFlushMode( FlushMode.MANUAL ).list() to retrieve the children.
Additionally, the poster has a fix posted which may solve the problem, or at least lay out the groundwork for a solution. Here is the proposed implementation of NamedQueryCollectionInitializer.initialize():
public void initialize(Serializable key, SessionImplementor session) throws HibernateException {
if (log.isDebugEnabled()) { log.debug("initializing collection: " + persister.getRole() + " using named query: " + queryName); }
// TODO: is there a more elegant way than downcasting? AbstractQueryImpl query = (AbstractQueryImpl) session .getNamedSQLQuery(queryName); if (query.getNamedParameters().length > 0) { query.setParameter(query.getNamedParameters()[0], key, persister .getKeyType()); } else { query.setParameter(0, key, persister.getKeyType()); }
List list = query.setCollectionKey(key).setFlushMode(FlushMode.MANUAL) .list();
// Uh, how 'bout we save the collection for later retrieval? CollectionKey collectionKey = new CollectionKey(persister, key, session .getEntityMode()); for (Object object : session.getPersistenceContext() .getCollectionsByKey().keySet()) { if (collectionKey.equals(object)) { PersistentCollection persistentCollection = session .getPersistenceContext().getCollection(collectionKey);
Serializable[] serializables = new Serializable[list.size()]; for (int i = 0; i < list.size(); i++) { serializables[i] = persister.getElementType().disassemble( list.get, session, persistentCollection.getOwner()); }
The issue is still present in Hibernate 5.0.11.Final. The collection is not initialized correctly in NamedQueryCollectionInitializer. It calls only the list() and does nothing with it.
Within the context of a One-to-Many relationship, NamedQueryCollectionInitializer .initialize() never actually populates the PersistantBag on the parent after it calls query.setCollectionKey( key ).setFlushMode( FlushMode.MANUAL ).list() to retrieve the children.
This is documented in the forums here: http://forums.hibernate.org/viewtopic.php?t=986428
Additionally, the poster has a fix posted which may solve the problem, or at least lay out the groundwork for a solution. Here is the proposed implementation of NamedQueryCollectionInitializer.initialize():
public void initialize(Serializable key, SessionImplementor session)
throws HibernateException {
if (log.isDebugEnabled()) {
log.debug("initializing collection: " + persister.getRole()
+ " using named query: " + queryName);
}
// TODO: is there a more elegant way than downcasting?
AbstractQueryImpl query = (AbstractQueryImpl) session
.getNamedSQLQuery(queryName);
if (query.getNamedParameters().length > 0) {
query.setParameter(query.getNamedParameters()[0], key, persister
.getKeyType());
} else {
query.setParameter(0, key, persister.getKeyType());
}
List list = query.setCollectionKey(key).setFlushMode(FlushMode.MANUAL)
.list();
// Uh, how 'bout we save the collection for later retrieval?
CollectionKey collectionKey = new CollectionKey(persister, key, session
.getEntityMode());
for (Object object : session.getPersistenceContext()
.getCollectionsByKey().keySet()) {
if (collectionKey.equals(object)) {
PersistentCollection persistentCollection = session
.getPersistenceContext().getCollection(collectionKey);
Serializable[] serializables = new Serializable[list.size()];
for (int i = 0; i < list.size(); i++) {
serializables[i] = persister.getElementType().disassemble(
list.get, session,
persistentCollection.getOwner());
}
persistentCollection.initializeFromCache(persister,
serializables, persistentCollection.getOwner());
persistentCollection.setSnapshot(key, persistentCollection
.getRole(), serializables);
persistentCollection.afterInitialize();
session.getPersistenceContext().getCollectionEntry(
persistentCollection).postInitialize(
persistentCollection);
}
}
}