Являются ли сущности кэшированы в jpa по умолчанию?
Я добавляю объект в свою базу данных, и он отлично работает. Но когда я получаю список, я получаю старый объект, новые объекты, которые я добавляю, пока не отображаются, пока я не разворачиваю приложение и не переустанавливаю его снова. Это означает, что мои сущности кэшируются по умолчанию? Но я не установил никаких настроек для кеширования сущностей в моем файле persistence.xml или любом таком файле.
Я даже попытался вызвать flush(), refresh() и merge(). Но все же он показывает только старые сущности. Я что-то упускаю? Пожалуйста, помогите мне.
Ответы
Ответ 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>
он работает!