hibernate API如何第二次从缓存中获取持久对象(第1级和第2级)。
我知道,首先从数据库中获取请求并提供持久对象,并将其放入第一级缓存(如果启用,也会进入第二级缓存)。
当我第二次查询它将如何从缓存中获取时? load()
和get()
将如何获取?
此外,equals()
,hashcode()
在持久性pojo中的作用是什么?基于此equals()
,它将从缓存中获取持久对象吗?
如果equals()
失败(以正确方式实施)将会发生什么,这意味着它每次都会进入数据库?
答案 0 :(得分:0)
当您在当前会话中管理Entity
时,会将其置于PersistenceContext
内。
每个load
或get
操作都会查询该上下文,如果Entity
存在,则返回它的实例,否则,它将命中数据库。它也适用于延迟加载。
Blog article with examples about this, used as reference
实施
时所需的equals()
和hashcode()
打算将持久化类的实例放在一个Set中(推荐的表示多值关联的方式)和 打算使用重新附加分离的实例
第一级缓存不使用equals()
方法来管理它的上下文。 StatefulPersistenceContext
使用EntityKey
。
@Override
public boolean containsEntity(EntityKey key) {
return entitiesByKey.containsKey( key );
}
来自DefaultLoadEventListener
班级
protected Object loadFromSessionCache(
final LoadEvent event,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options) throws HibernateException {
SessionImplementor session = event.getSession();
Object old = session.getEntityUsingInterceptor( keyToLoad );
if ( old != null ) {
// this object was already loaded
EntityEntry oldEntry = session.getPersistenceContext().getEntry( old );
if ( options.isCheckDeleted() ) {
Status status = oldEntry.getStatus();
if ( status == Status.DELETED || status == Status.GONE ) {
return REMOVED_ENTITY_MARKER;
}
}
if ( options.isAllowNulls() ) {
final EntityPersister persister = event.getSession()
.getFactory()
.getEntityPersister( keyToLoad.getEntityName() );
if ( !persister.isInstance( old ) ) {
return INCONSISTENT_RTN_CLASS_MARKER;
}
}
upgradeLock( old, oldEntry, event.getLockOptions(), event.getSession() );
}
return old;
}
所以不,缓存时不需要equals()
。