JPA EntityManager кеширование - PullRequest
       3

JPA EntityManager кеширование

2 голосов
/ 16 января 2012

У меня есть субъект, определенный следующим образом:

public class Version {
    @Id
    private Long id;
    private String content;
    @Transient
    private Model model;

    //...
}

Из того, что я вижу, когда операция find выполняется в Entity Manager, она создает SELECT в базовой базе данных только один раз, а затем объект кэшируется в Entity Manager. Однако я вижу, что если я присваиваю Model свойству model, это изменение не отражается в кэшированной сущности. Например. если в одном вызове выполняется операция find и назначается Model, когда я снова выполняю find из другого EJB, свойство model снова равно null. Это изменение не отражается в кэшированном объекте? Возможно, потому что это @Transient?

Ответы [ 3 ]

7 голосов
/ 16 января 2012

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

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

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

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

3 голосов
/ 28 мая 2016

Я должен не согласиться с @JB Низет. EntityManager и Siber в JPA предлагают расширенный контекст сохраняемости. Совсем не правда, что «кэш первого уровня выбрасывается сразу после завершения транзакции».

Контекст постоянства может быть либо областью действия транзакции - Постоянство Контекст «живет» для длины транзакции или расширенный - Контекст постоянства охватывает несколько транзакций.

https://web.archive.org/web/20131212234524/https://blogs.oracle.com/carolmcdonald/entry/jpa_caching

Решение, однако, верное, вы должны сохранить изменения в объекте, если вы хотите, чтобы он был изменен в кэше.

2 голосов
/ 16 января 2012

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

Если используется @CloneCopyPolicy, то объект из контекста постоянства будет клонирован в общийкэша, сохраняя переходные поля.

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

Если вы используете ткачествои доступ к полю, тогда по умолчанию это @CloneCopyPolicy, иначе @InstantiationCopyPolicy.Вы также можете настроить это, используя

Вы также можете управлять тем, что объединено в общий кеш, используя DescriptorEventListener и события postMerge / postClone.

...