Hibernate fetch fail for @ManyToOne of composite ID, the raison is that during the ID resolvation, entities are loaded from DB, not from the resultSet, or even from the session cache.
Code:
protected final Object resolveIdentifier(Serializable id, SessionImplementor session) throws HibernateException {
EntityPersister entityPersister = session.getFactory()
.getEntityPersister( getAssociatedEntityName() );
boolean isProxyUnwrapEnabled = unwrapProxy &&
entityPersister.isInstrumented( session.getEntityMode() );
proxyOrEntity = loader.instanceNotYetLoaded(rs, i, persisters[i], descriptors[i].getRowIdAlias(),
entityKey, lockModes[i], null, null, hydratedObjects, session);
return proxyOrEntity;
}
}
} catch (Exception e) {
throw new HibernateException(e);
}
The result of that is if you load 100 records of an Entity with a composit ID of two other Entites, you will have : 1 + 2 * 100 Queries !
My solution wich is tested OK
org.hibernate.type.EntityType
Code:
org.hibernate.type.EntityType
protected final Object resolveIdentifier(Serializable id, SessionImplementor session) throws HibernateException {
EntityPersister entityPersister = session.getFactory()
.getEntityPersister( getAssociatedEntityName() );
boolean isProxyUnwrapEnabled = unwrapProxy &&
entityPersister.isInstrumented( session.getEntityMode() );
/**** first check the session cache *****/
EntityKey entityKey = new EntityKey(id,
entityPersister, session.getEntityMode() );
Object proxyOrEntity = session.getPersistenceContext().getEntity( entityKey );
/**** second check the fetchs of resultSet *****/
if (proxyOrEntity!=null)
return proxyOrEntity;
try {
if ( loader!=null && !rs.isClosed() ){
final EntityAliases[] descriptors = loader.getEntityAliases_();
String[] identifierAliases = (String[]) PrivateAccessor.getPrivateField( entityPersister, "identifierAliases", true);
for (int i=0;i<descriptors.length;i++){
boolean founds = true;
for(int j=0;j<identifierAliases.length;j++){ if (descriptors[i].getSuffixedKeyAliases().length!=identifierAliases.length)
founds = false;
else
if (!descriptors[i].getSuffixedKeyAliases()[j].toString().startsWith(identifierAliases[j]))
founds = false;
}
if (!founds)
continue; proxyOrEntity = loader.instanceNotYetLoaded(rs, i, persisters[i], descriptors[i].getRowIdAlias(),
entityKey, lockModes[i], null, null, hydratedObjects, session);
return proxyOrEntity;
}
}
} catch (Exception e) {
throw new HibernateException(e);
}
proxyOrEntity = session.internalLoad(
getAssociatedEntityName(),
id,
eager,
isNullable() && !isProxyUnwrapEnabled
);
if ( proxyOrEntity instanceof HibernateProxy ) {
( ( HibernateProxy ) proxyOrEntity ).getHibernateLazyInitializer()
.setUnwrap( isProxyUnwrapEnabled );
}
return proxyOrEntity;
http://stackoverflow.com/questions/22687227/join-fetch-on-composite-id-embeded-not-working/22718934#22718934