Подтвердить что ты не робот

Обновление EntityManager

У меня есть веб-приложение, использующее JPA. Этот менеджер сущностей хранит множество энтузиастов, и вдруг я обновляю базу данных с другой стороны. Я использую MySQL, и я использую PhpMyAdmin и меняю строку.

Как сообщить диспетчеру сущности повторно синхронизировать, например. забыть все entites в кеше?

Я знаю, что существует метод refresh(Object), но есть ли возможность сделать refreshAll() или что-то, что в результате получается?

Уверен, что это дорогостоящая операция, но если это нужно сделать.

4b9b3361

Ответ 1

entityManager.getEntityManagerFactory().getCache().evictAll()

Refresh - это нечто иное, поскольку изменяет ваш объект. Эта строка будет просто empty the cache, поэтому, если вы извлекаете объекты, измененные вне диспетчера сущностей, она будет выполнять фактический запрос базы данных вместо использования устаревшего значения cached.

Ответ 2

У меня была аналогичная проблема, и строка evictAll() выше работала для меня.

В качестве альтернативы, аннотация @Cache в классе сущности тоже работала, с тем чтобы иметь возможность контролировать параметры кэширования:

@Cache(coordinationType=CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS)

Смотрите: http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching

Ответ 3

Ну, для некоторых людей (например, я), которые пытались добавить factory.getCache(). evictAll(); и не работает, и используется JPA + Hibernate, чтобы обновить запрос, добавьте подсказку org.hibernate.cacheMode в IGNORE. Пример:

em.createNamedQuery("SomeEntity.SomeNamedQuery")
  .setHint("org.hibernate.cacheMode", "IGNORE")
  .getResultList();

Ответ 4

cache.evictAll не работает для меня. Таким образом, чтобы получить данные, перенесенные из другого приложения, я формирую:

em.getTransaction().begin();
em.getTransaction().commit();

После этого мой запрос поиска извлекает обновленные данные. Я не знаю, если это очень безопасное решение, но оно работает правильно.

Ответ 5

Если вы используете EclipseLink вместо Hibernate, подсказка:

em.createNamedQuery("SomeEntity.SomeNamedQuery")
.setHint(QueryHints.REFRESH, true)
.getResultList();

Ответ 6

Когда вы читаете объект в EntityManager, он становится частью контекста постоянства, и тот же объект будет оставаться в EntityManager, пока вы не очистите его() и не получите новый EntityManager. Поэтому, если вы обновите базу данных, EntityManager не увидит изменения, если вы не вызовите refresh() для объекта или не очистите() EntityManager. Это не имеет ничего общего с общим кэшем (L2) или контекстом постоянства (L1). Если вы также используете общий кэш и обновляете базу данных напрямую, то ваш общий кэш будет устаревшим. Вам необходимо обновить() объект или пометить его как недопустимый для обновления при следующем запросе.

Код должен следовать так, как. DETACH ОБНОВИТЬ MERGE FLUSH

Ответ 7

Спасибо @Amold за ниже, это работало, и это сделало мой день :)

@Cache (coordinationType = CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS)