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

Являются ли сущности кэшированы в jpa по умолчанию?

Я добавляю объект в свою базу данных, и он отлично работает. Но когда я получаю список, я получаю старый объект, новые объекты, которые я добавляю, пока не отображаются, пока я не разворачиваю приложение и не переустанавливаю его снова. Это означает, что мои сущности кэшируются по умолчанию? Но я не установил никаких настроек для кеширования сущностей в моем файле persistence.xml или любом таком файле.

Я даже попытался вызвать flush(), refresh() и merge(). Но все же он показывает только старые сущности. Я что-то упускаю? Пожалуйста, помогите мне.

4b9b3361

Ответ 1

Добро пожаловать в JPA. Если вы его используете, это означает, что у вас будут большие проблемы, если вы обновите базу данных за пределами JPA, если не знаете, что делаете, и очень осторожны. Это означает, что вам нужно выяснить, как очистить любые кэшированные объекты, чтобы их можно было перезагрузить.

В принципе, не обновляйте сущности за пределами JPA, если вы вообще можете им помочь, и если вы это сделаете, вам, вероятно, придется вдаваться в работу модели кэширования, используемой вашим конкретным провайдером JPA. Если вам нужно обновить внешний JPA, тогда JPA, вероятно, не подходит для вас.

Ответ 2

Это означает, что мои сущности кэшируются по умолчанию?

JPA 1.0 не определяет кеш L2 ( "общий кэш" ), JPA 1.0 определяет только кеш L1 ( "транзакционный кеш" ), но провайдеры JPA могут поддерживать общий кэш объектов, и большинство из них. Это относится к TopLink Essentials, который поддерживает кеши L1 и L2 через расширения JPA для кэширования (за JVM).

Теперь, как объяснено в замечательной статье Понимание кеша TopLink Essentials (GlassFish JPA):

  • Все EntityManager из одного и того же устройства сохранения сохраняют кеш сеанса (то, как TopLink вызывает кеш 2-го уровня).
  • Кэш сеанса включен по умолчанию.
  • Если в контексте персистентности есть изменения/удаления сущностей, они синхронизируются с кешем сеанса после транзакции, поэтому состояние кеша сеанса обновляется (или такой кеш не будет можно использовать вообще).

Таким образом, в вашей настройке должно быть что-то еще не так. Вы можете попробовать отключить общий кеш сеанса для целей тестирования (и только для целей тестирования), добавив следующее свойство:

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

Но я был бы удивлен, если это что-то изменит. Как я уже сказал, я думаю, что есть другая проблема.

PS: Это не отвечает на вопрос, но если вы используете GlassFish v3, почему бы вам не использовать EclipseLink?

Обновление: ответ на комментарий OP

Итак, если я сохраняю запись сотрудника, то он отображается в базе данных, но не в коллекции сотрудников в отделе, пока я не добавлю его в коллекцию сотрудников. Это необходимый шаг?

Ну, если вы не создаете связь между объектами на уровне Java, JPA не сможет создать ее в базе данных (JPA делает только то, что вы ему говорите). Итак, да, вам нужно создать ссылку, и в случае двунаправленной связи вам даже нужно установить обе стороны ссылки (например, добавить employee в коллекцию сотрудников на Department и установите Department для employee).

Ответ 3

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

У EntityManager всегда будет кеш константы (L1), пока вы не вызове clear() или не создадите новый.

Вы можете отключить общий кэш,

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

Но ваша проблема в том, что вы не поддерживаете обе стороны своих отношений. Когда вы устанавливаете 1-1, вам нужно добавить к 1-м, в противном случае ваши объекты недействительны.

Для получения дополнительной информации о кэшировании см.

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

Ответ 4

Используете ли вы EntityManager? если не дать ему попробовать http://docs.oracle.com/javaee/5/api/javax/persistence/EntityManager.html

Используете ли вы DataSource для управления соединениями с вашей базой данных? вы также должны попробовать. Является xml, который настроен на вашем сервере. Предоставьте больше информации о своей архитектуре, чтобы мы могли вам помочь.

Ответ 5

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

<shared-cache-mode>NONE</shared-cache-mode>

он работает!