Отключить кеширование в JPA (eclipselink) - PullRequest
43 голосов
/ 11 мая 2010

Я хочу использовать JPA (eclipselink) для получения данных из моей базы данных. База данных изменяется рядом других источников, и поэтому я хочу вернуться к базе данных для каждой находки, которую я выполняю. Я прочитал несколько постов по отключению кеша, но это, похоже, не работает. Есть идеи?

Я пытаюсь выполнить следующий код:

        EntityManagerFactory entityManagerFactory =  Persistence.createEntityManagerFactory("default");
        EntityManager em = entityManagerFactory.createEntityManager();

        MyLocation one = em.createNamedQuery("MyLocation.findMyLoc").getResultList().get(0);

        MyLocation two = em.createNamedQuery("MyLocation.findMyLoc").getResultList().get(0);    

        System.out.println(one==two);

one == два - это правда, а я хочу, чтобы оно было ложным.

Я попытался добавить все / все последующие в мой файл persistence.xml

<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.cache.size.default" value="0"/>
<property name="eclipselink.cache.type.default" value="None"/>

Я также попытался добавить аннотацию @Cache к самой сущности:

@Cache(
  type=CacheType.NONE, // Cache nothing
  expiry=0,
  alwaysRefresh=true
)

Я что-то неправильно понимаю?

Ответы [ 7 ]

39 голосов
/ 11 мая 2010

Это правильное поведение, иначе, если вы измените объект один и объект два с разными значениями, у вас будут проблемы при сохранении их. Происходит то, что вызов загрузки объекта два обновляет объект, загруженный при первом вызове. Они должны указывать на один и тот же объект, поскольку они являются одним и тем же объектом. Это гарантирует, что грязные данные не могут быть записаны.

Если вы вызываете em.clear () между двумя вызовами, сущность один должна отключиться, и ваш чек вернет false. Однако в этом нет необходимости, ссылка на затмение фактически обновляет ваши данные до последней версии, которая, как я предполагаю, вам нужна, поскольку она часто меняется.

С другой стороны, если вы хотите обновить эти данные с помощью JPA, вам необходимо получить пессимистичные блокировки для сущности, чтобы базовые данные не могли измениться в БД.

Вам нужно будет отключить кеш запросов, так как ваши параметры кеша просто удаляли кеш объекта из игры, а не кеш запроса, поэтому вы не получаете новые результаты:

В вашем коде:

em.createNamedQuery("MyLocation.findMyLoc").setHint(QueryHints.CACHE_USAGE, CacheUsage.DoNotCheckCache).getResultList().get(0);

Или в файле persistence.xml:

<property name="eclipselink.query-results-cache" value="false"/>
25 голосов
/ 04 декабря 2012
final Query readQuery = this.entityManager.createQuery(selectQuery);
readQuery.setParameter(paramA, valueA);

// Update the JPA session cache with objects that the query returns.
// Hence the entity objects in the returned collection always updated.
readQuery.setHint(QueryHints.REFRESH, HintValues.TRUE);

entityList = readQuery.getResultList();

Это работает для меня.

12 голосов
/ 16 октября 2015

Если вы хотите отключить кэширование без указания поставщика, вы можете пометить свой объект домена с помощью:

@Cacheable(false)

Вот пример:

@Entity
@Table(name="SomeEntity")
@Cacheable(false)
public class SomeEntity {
    // ...
}
10 голосов
/ 05 декабря 2012

См.,

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching

Для одного и того же EntityManager JPA всегда требуется один == два, так что это правильно, независимо от ваших параметров кэширования (это кэш L1,или кэш транзакций, который обеспечивает изоляцию вашей транзакции и поддерживает идентичность объекта).

Чтобы принудительно обновить запрос (и отменить все внесенные вами изменения), вы можете использовать подсказку запроса "eclipselink.refresh" = "true».Или, возможно, лучше использовать новый EntityManager для каждого запроса / запроса или вызвать clear () в EntityManager.

<property name="eclipselink.cache.shared.default" value="false"/>

Это правильный способ отключить общий кэш (кэш L2).Удалите все остальные настройки, так как они неверны и могут вызвать проблемы.

EclipseLink по умолчанию не поддерживает кэш запросов, поэтому эти настройки не будут влиять.CacheUsage также не корректен, не используйте его (он предназначен для запросов в памяти).

3 голосов
/ 08 марта 2018

Кэш первого уровня включен по умолчанию, и вы не можете его отключить. то есть никакие настройки в вашем файле persistence.xml не отключат кэш первого уровня.

Вы можете очистить все объекты менеджера сущностей, вызвав

entityManager.clear()

это приведет к тому, что последующие запросы будут отправлены в базу данных (в первый раз), а затем объекты снова сохранятся в кеше

Вы можете заставить каждый запрос идти в базу данных напрямую, вызвав

query.setHint("javax.persistence.cache.storeMode", CacheStoreMode.REFRESH);
3 голосов
/ 23 августа 2016

Я знаю, что это сообщение может быть старым, но я пишу для тех, кто нуждается в помощи. У меня была эта проблема, и наконец я решил ее с помощью этого кода:

em.createNamedQuery("findAll").setHint(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.BYPASS).getResultList();

Это работает очень хорошо. И мы можем видеть в javadoc перечисления BYPASS, написано, что:

Обход кеша: получение данных напрямую из базы данных.

Я должен заметить, что я использую Weblogic 12c и TopLink в качестве реализации JPA.

3 голосов
/ 11 августа 2010

Если вручную изменить атрибуты объекта, например MyLocation. Приведенный выше трюк (CACHE_USAGE=CacheUsage.DoNotCheckCache или eclipselink.query-results-cache=false), похоже, не работает, как я пытался.

Итак, я попытался установить другую подсказку, которая eclipselink.refresh, на true. тогда это работает. Я имею в виду, что измененные вручную атрибуты возвращаются.

Так что, как я понимаю, вышеупомянутый трюк только гарантирует, что он получает правильные объекты. Однако, если объекты уже были кэшированы, eclipselink просто возвращает их, не проверяя свежесть содержимого объектов. Только когда подсказка eclipselink.refresh установлена ​​на true, эти объекты будут обновляться для отражения последних значений атрибутов.

...