簡體   English   中英

JPA EntityManager緩存

[英]JPA EntityManager caching

我有一個實體定義如下:

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

    //...
}

從我所看到的,當在Entity Manager上完成find操作時,它只對基礎數據庫進行一次SELECT ,然后將實體緩存在實體管理器中。 但是,我看到如果我將Model分配給model屬性,則此更改不會反映到緩存實體。 例如,如果在一次調用中,完成了find操作並分配了Model ,當我從另一個EJB中再次find時, model屬性再次為null 此更改是否未反映到緩存實體? 也許是因為它是@Transient

實體管理器維護第一級緩存,並且一旦事務結束,該第一級緩存就被丟棄。 否則,緩存將返回過時值,因為在同一應用程序或另一個應用程序中的其他事務可以修改或刪除緩存的實體。

而且,並發事務每個都有自己的會話級緩存,因此它們自己的實例是同一個實體。

如果在后續事務中,您find相同的實體,則將發出新的SQL查詢,並將返回該實體的不同實例。

如果必須在給定實體的事務之間記住某些內容,則應該在數據庫中使其保持不變。 這就是數據庫的重點。

我不同意@JB Nizet。 JPA的EntityManager和Hibernate的Session提供了擴展的持久化上下文。 一旦交易結束,“第一級緩存就會被拋棄”,這一點都不是真的。

持久化上下文可以是事務范圍 - 持久化上下文“生存”為事務的長度,或者擴展 - 持久性上下文跨越多個事務。

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

但是,解決方案是正確的,如果要在緩存中更改對象,則必須對對象進行持久更改。

如果您正在使用EclipseLink,則可以通過兩種方式配置合並到瞬態共享緩存中。

如果使用@CloneCopyPolicy,則持久化上下文中的對象將被克隆到共享緩存中,從而保留瞬態字段。

如果使用@InstantiationCopyPolicy,則將為共享緩存創建新實例,並且不會保留瞬態。

如果您正在使用編織和字段訪問,則默認為@CloneCopyPolicy,否則為@InstantiationCopyPolicy。 您也可以使用配置

您還可以使用DescriptorEventListener和postMerge / postClone事件控制合並到共享緩存中的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM