我们可以使用JPA2注释来缓存关联吗?



我现在在我的实体上使用JPA2 @Cacheable注释,并且一切都运行良好。

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

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

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

这行得通。但似乎我们不能在实体本身以外的任何地方使用JPA2 @Cacheable注释。

我错过了什么,还是JPA委员会太模糊,无法意识到必须缓存关联以及实体?当然,这不会是一个糟糕的选择吧?

我想经过一番研究,我能够回答我自己的问题。关键是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;
}
为Hibernate

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

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

Student数据中的最后一个1为tutor的外键。

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

然而,如果你走另一条路,在导师上调用getStudents(),在2LC中没有外键,所以需要一个选择。(一旦选择完成,hibernate就有了id,可以开始点击2LC)。

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

为EclipseLink

我没有EclipseLink安装的手,所以我不能测试这一点,但我知道,EclipseLink存储2LC数据的原始对象图的形式,所以上面是不相关的。根据Chris的回答,实体与它的引用一起缓存,因此不需要进一步的注释。

JPA的缓存是针对实体对象本身的。只要实体被缓存,所有引用也都会被缓存。被引用的实体对象有自己的缓存选项。

最新更新