Обновление EntityManager - PullRequest
       8

Обновление EntityManager

27 голосов
/ 29 апреля 2011

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

Как сообщить менеджеру сущности о повторной синхронизации, например, забыть все объекты в кеше?

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

Конечно, это дорогостоящая операция, но если это необходимо сделать.

Ответы [ 6 ]

36 голосов
/ 29 апреля 2011
entityManager.getEntityManagerFactory().getCache().evictAll()

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

8 голосов
/ 06 апреля 2012

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

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

@Cache(coordinationType=CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS)

См .: http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching

3 голосов
/ 24 августа 2015

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

em.createNamedQuery("SomeEntity.SomeNamedQuery")
  .setHint("org.hibernate.cacheMode", "IGNORE")
  .getResultList();
2 голосов
/ 29 марта 2017

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

em.createNamedQuery("SomeEntity.SomeNamedQuery")
.setHint(QueryHints.REFRESH, true)
.getResultList();
2 голосов
/ 18 марта 2016

cache.evict Все у меня не работает.Поэтому для извлечения данных, извлеченных из другого приложения, я выполняю следующую команду:

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

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

0 голосов
/ 02 мая 2018

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

Код должен следовать следующим образом.DETACH REFRESH MERGE FLUSH

...