开发者

Hibernate session.contains( Class clazz, Serializable id )

I want to be able to check whether a session contains an entity of a given class/identifier. I can't see a way to do this at the moment.

  • contains() takes an entity ob开发者_开发技巧ject not class + key
  • get() queries the database if the entity is not present which I don't want to do
  • load() never returns null as a proxy is always created so I can't use this method

Is it possible to do the above with no side-effects/queries to DB?


This works:

public boolean isIdLoaded(Serializable id)
{
    for (Object key : getSession().getStatistics().getEntityKeys())
    {
        if (((EntityKey) key).getIdentifier().equals(id))
        {
            return true;
        }
    }

    return false;
}


Not that I know of. The session will always check the DB if you attempt to get an entity of a particular type and id and it doesn't contain it.

In fact that is one of the good things about the model. You don't have to care where JPA/Hibernate gets the object from, cache (1st or 2nd level) or the DB.

If you have an entity in memory you can check to see if it is dettached from the session but not if it is in the session.


Answering my own question.

I do not believe this is possible with the public APIs. However if you are willing to tolerate some cheese you can do the following

        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;

This relies on internal APIs of hibernate so may not work in future if it changes internally.


public static boolean sessionContains(Session session, Class<?> aClass, Serializable id) {
    return Hibernate.isInitialized(session.load(aClass, id));
}

session#load() doesn't go to the database and always return Object. If returned value is a Proxy then session doesn't contain passed id/class pair. Otherwise session already has this object.


PersistenceUnitUtil persistenceUnitUtil = entityManagerFactory.getPersistenceUnitUtil();
Object object = entityManager.getReference(entity.getClass(), entity.getId());
boolean inSessionCache = persistenceUnitUtil.isLoaded(object);

If entity is in Session cache then getReference() return entity, else it return proxy object. isLoaded() return false if object is proxy.


Use getIdentifier(..). It returns the identifier value of the given entity as associated with current session see Javadoc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜