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


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

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

5 17

5 ответов:

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

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

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

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

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

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

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

<property name="toplink.cache.shared.default" value="false"/>
Но я был бы удивлен, если бы это что-нибудь изменило. Как я уже сказал, Я думаю, что где-то есть еще одна проблема.

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

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

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

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

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

Вы используете EntityManager? если нет, попробуйте http://docs.oracle.com/javaee/5/api/javax/persistence/EntityManager.html

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

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

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

Это действительно работает!