Java Hibernate会话。包含(类clazz,可序列化id)
我希望能够检查会话是否包含给定类/标识符的实体。我现在找不到这样做的方法Java Hibernate会话。包含(类clazz,可序列化id),java,hibernate,session,Java,Hibernate,Session,我希望能够检查会话是否包含给定类/标识符的实体。我现在找不到这样做的方法 contains() get() load()永远不会返回null,因为始终会创建代理,因此我无法使用此方法 是否可以在没有副作用/对DB的查询的情况下执行上述操作?我不知道。如果您试图获取特定类型和id的实体,而该实体不包含该实体,则会话将始终检查数据库 事实上,这是该模型的优点之一。您不必关心JPA/Hibernate从何处获取对象、缓存(第一级或第二级)或数据库 如果内存中有实体,可以检查它是否已从会话中删除,但
contains()
get()
永远不会返回null,因为始终会创建代理,因此我无法使用此方法load()
是否可以在没有副作用/对DB的查询的情况下执行上述操作?我不知道。如果您试图获取特定类型和id的实体,而该实体不包含该实体,则会话将始终检查数据库 事实上,这是该模型的优点之一。您不必关心JPA/Hibernate从何处获取对象、缓存(第一级或第二级)或数据库
如果内存中有实体,可以检查它是否已从会话中删除,但不检查它是否在会话中 使用
getIdentifier(..)
。它返回与当前会话相关的给定实体的标识符值。请参见。回答我自己的问题
我认为这在公共API中是不可能的。然而,如果你愿意忍受一些奶酪,你可以做以下事情
SessionImplementor sessionImplementor = ((SessionImplementor)session);
EntityPersister entityPersister = sessionImplementor.getFactory().getEntityPersister( clazz.getName() );
PersistenceContext persistenceContext = sessionImplementor.getPersistenceContext();
EntityKey entityKey = new EntityKey( id, entityPersister, EntityMode.POJO );
Object entity = persistenceContext.getEntity( entityKey );
if ( entity != null )
return entity;
entity = persistenceContext.getProxy( entityKey );
if ( entity != null )
return entity;
return null;
这依赖于hibernate的内部API,因此如果它在内部发生更改,将来可能无法工作。这可以工作:
public boolean isIdLoaded(Serializable id)
{
for (Object key : getSession().getStatistics().getEntityKeys())
{
if (((EntityKey) key).getIdentifier().equals(id))
{
return true;
}
}
return false;
}
public静态布尔sessionContains(会话会话、类aClass、可序列化id){
返回Hibernate.i初始化(session.load(aClass,id));
}
session#load()
不会转到数据库并始终返回对象。
若返回的值是代理,那个么会话不包含传递的id/类对。
否则会话已经有了这个对象。只是好奇-为什么需要知道具有给定标识符的对象是否在会话中?难道你不能只执行
get(id)
并依赖这样一个事实,即如果对象已经在会话中,Hibernate将返回该实例,而不是重新查询它吗?在这个实例中,我试图让Hibernate与一些自定义缓存交互,但只在非常特定的实例中进行交互,大多数时候,我对点击DB的默认行为感到高兴,因此我想检查会话中是否存在对象,如果不从缓存加载它的话。关键是我不能干扰会话中已经存在的任何内容,因为可能有来自其他对象的多对一引用对它的引用。@MikeQ您对IdentityMap的工作方式完全正确,因此我的答案现在被删除。这不是我想要的。您错了。session#load and session#getReference始终创建代理,从不检查数据库。
public static boolean sessionContains(Session session, Class<?> aClass, Serializable id) {
return Hibernate.isInitialized(session.load(aClass, id));
}