Hibernate succeeded to retrieve Query Result from cache, then it failed to retrieve Entities from Cache, it executed a single Query for every row.
I debugged org.hibernate.event.internal.DefaultLoadEventListener
, and in my case persister.hasNaturalIdentifier()
returned false
, so looks like entities are never cached.
I was expecting that the ID should be used as a default KEY.
protected Object doLoad(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options) {
Object entity = loadFromSessionCache( event, keyToLoad, options );
entity = loadFromSecondLevelCache( event, persister, options );
if ( entity != null ) {
}
else {
entity = loadFromDatasource( event, persister, keyToLoad, options );
}
if ( entity != null && persister.hasNaturalIdentifier() ) {
event.getSession().getPersistenceContext().getNaturalIdHelper().cacheNaturalIdCrossReferenceFromLoad(
persister,
event.getEntityId(),
event.getSession().getPersistenceContext().getNaturalIdHelper().extractNaturalIdValues(
entity,
persister
)
);
}
return entity;
}
SO after
1_ the loadFromSecondLevelCache Faileds
2_ it load from Datasource,
3_ then it should put the Entity in the Cache wich is not possible because persister.hasNaturalIdentifier()
returned false
If i am wrong where is the hibernate sequence for the insert of the Entity to the cache after the load?
After some search my problem is exactly this secondlevelcache
And it also a duplicate of this coherence-hibernate-integration/1.0.0/secondlevelcache
So the real problem is
During the creation of the cacheKey hibernate use persister.getRootEntityName()
final CacheKey cacheKey = session.generateCacheKey( id, persister.getIdentifierType(), persister.getRootEntityName() );
if ( session.getPersistenceContext().wasInsertedDuringTransaction( persister, id ) ) {
persister.getCacheAccessStrategy().update(
cacheKey,
persister.getCacheEntryStructure().structure( entry ),
version,
version
);
}
But during the retrive it use persister.getEntityName() !!!!
protected Object loadFromSecondLevelCache(
final LoadEvent event,
final EntityPersister persister,
final LoadEventListener.LoadType options) {
final SessionImplementor source = event.getSession();
final boolean useCache = persister.hasCache()
&& source.getCacheMode().isGetEnabled()
&& event.getLockMode().lessThan( LockMode.READ );
if ( !useCache ) {
// we can't use cache here
return null;
}
final SessionFactoryImplementor factory = source.getFactory();
final CacheKey ck = source.generateCacheKey(
event.getEntityId(),
persister.getIdentifierType(),
persister.getEntityName()
);