【问题标题】:Can we use JPA2 annotations to cache associations?我们可以使用 JPA2 注释来缓存关联吗?
【发布时间】:2012-12-31 04:17:03
【问题描述】:

我现在在我的实体上使用 JPA2 @Cacheable 注释,一切正常。

我现在需要缓存一个多对一关联。

在经典的 Hibernate 中,有必要用 @Cache 注释关联。

@org.hibernate.annotations.Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Student> supervisionGroup;

这很有效。但似乎我们不能在实体本身以外的任何东西上使用 JPA2 @Cacheable 注释。

是我遗漏了什么,还是 JPA 委员会太模糊而没有意识到关联和实体一样必须被缓存?肯定不会是暗淡的选项吧??

【问题讨论】:

    标签: hibernate jpa jpa-2.0 second-level-cache


    【解决方案1】:

    我认为经过一些研究,我能够回答我自己的问题。关键是 Hibernate 将 2LC 中的对象脱水,这将影响您是否需要显式缓存关联。

    如果我遗漏了任何内容或有任何细节错误,请添加更多详细信息。

    这是一个简化的类结构:

    @Entity
    @Cacheable
    public class Tutor
    {
       @OneToMany(mappedBy="tutor")
       private Set<Student> students;
    }
    
    @Entity
    @Cacheable
    public class Student
    {
       @ManyToOne(fetch=FetchType.LAZY)
       @JoinColumn(name="TUTOR_FK")
       private Tutor tutor;
    }
    

    对于休眠

    二级缓存 (2LC) 以脱水形式存储实体,例如:

    {1=CacheEntry(Tutor)[1, Jack Daw]}
    {1=CacheEntry(Student)[1, Jane Smith, 1]}    
    

    Student数据中最后的1是tutor的外键。

    因此,如果您有对学生 id 1 的引用并遵循对导师的引用,我们会得到缓存命中,因为外键在缓存中。不需要额外的选择。

    但是,如果您采用其他方式,在 Tutor 上调用 getStudents(),则 2LC 中没有外键,因此需要选择。 (一旦选择完成,hibernate 就有了 ids 并且可以开始命中 2LC)。

    为避免这种情况,您需要将旧的 org.hibernate.annotations.Cache 注释添加到 @OneToMany 关系中。

    对于 EclipseLink

    我手头没有 EclipseLink 安装,因此无法对此进行测试,但我了解 EclipseLink 以原始对象图的形式存储 2LC 数据,因此与上述无关。根据 Chris 的回答,实体与其引用一起被缓存,因此不需要进一步注释。

    【讨论】:

    • 感谢您的信息。缓存了多少个关联(它们是否被缓存?)。因为它完全是一张不同的桌子。 FK id 不会保存在父表中。 ?
    【解决方案2】:

    JPA 的缓存用于实体对象本身。只要实体被缓存,所有引用也是如此。引用的实体对象虽然会有自己的缓存选项。

    【讨论】:

    • 谢谢 - 我的基本测试表明在使用引用对象时缓存未命中,但是当我使用旧的 o.h.a.Cache 注释时,我再次被命中。但我会再次测试并报告。
    • 好的,我的测试证实使用 Hibernate,关系没有被缓存,有必要回退到 org.hibernate 注释。这可能是休眠的一个怪癖,其他提供者免费实现集合缓存吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 2011-04-12
    • 1970-01-01
    • 2018-02-19
    • 2011-07-06
    相关资源
    最近更新 更多