Hibernate session.contains (Класс clazz, Сериализуемый идентификатор) - PullRequest
6 голосов
/ 19 сентября 2011

Я хочу иметь возможность проверить, содержит ли сеанс сущность данного класса / идентификатора. Я не вижу способа сделать это в данный момент.

  • contains() принимает объект сущности, а не класс + ключ
  • get() запрашивает базу данных, если объект отсутствует, что я не хочу делать
  • load() никогда не возвращает ноль, поскольку прокси всегда создается, поэтому я не могу использовать этот метод

Возможно ли сделать вышеупомянутое без побочных эффектов / запросов к БД?

Ответы [ 5 ]

4 голосов
/ 05 мая 2012

Это работает:

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

    return false;
}
1 голос
/ 21 сентября 2011

Отвечая на мой собственный вопрос.

Я не верю, что это возможно с общедоступными 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;

Это зависит от внутренних API hibernate, поэтому может не работать в будущем, если оно изменится внутренне.

1 голос
/ 19 сентября 2011

Не то, что я знаю. Сессия всегда будет проверять БД, если вы попытаетесь получить сущность определенного типа и идентификатора, и она не будет содержать ее.

На самом деле это одна из хороших вещей в модели. Вам не нужно заботиться о том, откуда JPA / Hibernate получает объект, кеш (1-й или 2-й уровень) или БД.

Если у вас есть объект в памяти, вы можете проверить, извлечен ли он из сеанса, но нет, если он находится в сеансе.

0 голосов
/ 24 января 2019
public static boolean sessionContains(Session session, Class<?> aClass, Serializable id) {
    return Hibernate.isInitialized(session.load(aClass, id));
}

session#load() не идет в базу данных и всегда возвращает объект.Если возвращаемое значение является Proxy, то сеанс не содержит переданную пару id / class.В противном случае сессия уже имеет этот объект.

0 голосов
/ 19 сентября 2011

Используйте getIdentifier(..).Он возвращает значение идентификатора данного объекта, связанного с текущим сеансом, см. Javadoc .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...