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

时间:2013-01-16 18:33:59

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

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

我现在需要缓存ManyToOne关联。

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

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

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

我是否遗漏了某些内容,或者JPA委员会是否过于朦胧而无法意识到协会必须被缓存以及实体?当然它不能是昏暗的选择??

2 个答案:

答案 0 :(得分: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;
}

对于Hibernate

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

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

学生数据中的最后一个是导师的外键。

因此,如果你有一个Student id 1的引用并且跟随对教师的引用,我们会得到一个缓存命中,因为外键在缓存中。无需额外选择。

但是,如果你走另一条路,在Tutor上调用getStudents(),2LC中没有外键,因此需要select。 (一旦选择完成,hibernate就会有id并且可以开始点击2LC)。

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

对于EclipseLink

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

答案 1 :(得分:0)

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