【问题标题】:Hibernate second level cache is not used in every case并非在所有情况下都使用 Hibernate 二级缓存
【发布时间】:2020-01-13 13:39:53
【问题描述】:

使用 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);

我有以下会话指标:

    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 语句,但事实并非如此。

【问题讨论】:

    标签: java spring hibernate spring-boot jpa


    【解决方案1】:

    二级缓存仅在通过其 id 检索实体时起作用,无论是使用 EntityManager.find(...) 还是在 JPA 需要获取相关实体时在内部进行。默认情况下从不缓存查询结果。

    您想要的是Hibernate query cacheorg.hibernate.cacheable 查询提示。或者,您可以启用 Spring 缓存并使用 @Cacheable@CachePut 注释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      • 2012-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多