Hibernate成功从缓存中检索查询结果, 然后它无法从缓存中检索实体,它为每一行执行了一个查询。
我调试了org.hibernate.event.internal.DefaultLoadEventListener
,在我的情况下persister.hasNaturalIdentifier()
返回了false
,所以看起来实体永远不会被缓存。
我原以为ID应该用作默认的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;
}
之后
1 _ loadFromSecondLevelCache失败
2 _ 从Datasource加载
3 _ 然后它应该将实体放入缓存中,因为persister.hasNaturalIdentifier()
返回false
如果我错了在加载后将实体插入缓存的hibernate序列在哪里?
经过一番搜索,我的问题正是这个secondlevelcache
它也是此coherence-hibernate-integration/1.0.0/secondlevelcache
的副本所以真正的问题是
在创建cacheKey hibernate期间使用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
);
}
但在回溯过程中使用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()
);
答案 0 :(得分:0)
Hibernate按ID搜索缓存,而不是通过natural-id,检查此调用:
entity = loadFromSecondLevelCache( event, persister, options );
在您的情况下,可能是缓存条目因未决的并发实体修改而失效。
答案 1 :(得分:0)
更改 org.hibernate.engine.internal.TwoPhaseLoad
final CacheKey cacheKey = session.generateCacheKey( id,
persister.getIdentifierType(), persister.getRootEntityName() );
--->
final CacheKey cacheKey = session.generateCacheKey( id,
persister.getIdentifierType(), persister.getEntityName() );
解决问题,但我愿意接受更好的解决方案