10

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

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

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

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

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

我是否遗漏了什么,或者 JPA 委员会太模糊而没有意识到关联必须与实体一样被缓存?当然它不能是暗淡的选择??

4

2 回答 2

4

我想经过一些研究,我能够回答我自己的问题。关键是 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 是辅导的外键。

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

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

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

对于 EclipseLink

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

于 2013-01-17T18:24:46.050 回答
0

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

于 2013-01-16T18:44:57.893 回答