使用 Spring Boot 2、Spring Data JPA 和 Hibernate。我正在尝试对一些从未更新的实体使用 Hibernate 的二级缓存。
在我的例子中,实体DocumentType
与其他实体相关,因此当查询一种文档类型时,Hibernate 会进行 4 个 sql 查询。
当使用Hibernate二级缓存时,缓存用于某些实体,但仍然有一个sql查询到数据库。
我想了解为什么在一种情况下不使用缓存。
这就是我的实体的样子:
@Entity
@Table(name = "document_type")
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class DocumentType {
@Id
private Long id;
@Column
private String subtypeCode;
@OneToOne(cascade = {CascadeType.ALL})
private Translation translation;
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "business", joinColumns = @JoinColumn(name = "document_type_id"))
@Enumerated(EnumType.STRING)
@Column(name = "business")
private Set<Business> businesses;
@ManyToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "equivalence_id")
private Equivalence equivalence;
@Entity
@Table(name = "equivalence")
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Equivalence {
@Id
private Long id;
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@OneToMany(mappedBy="equivalence", fetch = FetchType.EAGER)
private List<DocumentType> documentTypeList;
当我第一次使用此方法获取文档类型时:
@Repository
public interface DocumentTypeRepository extends JpaRepository<DocumentType, Long> {
DocumentType findBySubtypeCode(String subtypeCode);
我有以下 session 指标:
1704919 nanoseconds spent preparing 4 JDBC statements;
33284024 nanoseconds spent executing 4 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
2983589 nanoseconds spent performing 4 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
1313315 nanoseconds spent performing 3 L2C misses;
第二次获取相同的文档类型会给出:
27855 nanoseconds spent preparing 1 JDBC statements;
4348289 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
14421 nanoseconds spent performing 1 L2C puts;
182655 nanoseconds spent performing 3 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
我希望第二次有 0 条 JDBC 语句,但事实并非如此。
最佳答案
二级缓存仅在通过 ID 检索实体时才起作用,可以使用 EntityManager.find(...)
或者当 JPA 需要获取相关实体时在内部。默认情况下,查询结果不会被缓存。
你想要的是Hibernate query cache和 org.hibernate.cacheable
查询提示。或者,您可以启用 Spring 缓存并使用 @Cacheable
或@CachePut
注解。
关于java - Hibernate二级缓存并不是在所有情况下都使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57893801/