【发布时间】:2019-04-29 01:00:23
【问题描述】:
afaik 实体仅通过其在二级缓存中的主键进行索引,因此查询相关实体不会使用它:
@Entity
public class Employee {
@Id
@Column(name="EMP_ID")
private long id;
...
@OneToMany(mappedBy="owner")
private List<Phone> phones;
...
}
@Entity
public class Phone {
@Id
private long id;
...
@ManyToOne
@JoinColumn(name="OWNER_ID")
private Employee owner;
...
}
EntityManager em;
// uses 2nd level cache
Employee employee = em.find(Employee.class, 1);
// doesn't use 2nd level cache. Even if 2nd level cache actually
// contains all referenced phones, there will be a DB call.
employee.getPhones();
在访问手机并使用二级缓存时,是否可以避免 db 调用?是否有支持自定义索引的缓存实现?
我目前正在使用带有 hibernate/infinispan 的 Wildfly 14。
访问手机至少会使用查询缓存还是只使用em.createQuery(...)?
【问题讨论】:
-
如果 JPA 提供程序已在
Employee的 L2 缓存条目中缓存了相关Phones 的“id”,那么它应该不需要转到数据库。它获取Employee的二级缓存条目,然后查找相关ID 的二级缓存条目。我使用的 JPA 提供程序(不是 Hibernate)就是这样做的。 -
您使用哪个 JPA 提供程序?在 infinispan 旁边,我已经尝试过 ehcache,它的行为相同。
-
我使用 DataNucleus。使用一些不同的 L2 缓存不是问题...... JPA 提供者决定 L2 缓存中的内容以及访问时间。也许看看你的 JPA 提供者在 L2 缓存中存储了什么,如果还没有完成,也许他们也可以选择存储关系?
-
是否有 JPA 指定的通用配置来启用这种行为?还是在休眠中?我无法更改为其他提供商。
-
缓存提供者,例如 Infinispan,将实体视为黑色对象,因此我们通常不会尝试对实体进行脱水以进一步缓存事物...如果您想尝试更小规模的事物,您可以用你的数据模型修改this Infinispan + Hibernate simple tutorial看看。
标签: java hibernate jpa wildfly infinispan