当前位置: 首页 > 知识库问答 >
问题:

Hibernate二级缓存不是在每种情况下都使用

解阳泽
2023-03-14

使用SpringBoot2、SpringDataJPA和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语句,但事实并非如此。

共有1个答案

楚俊迈
2023-03-14

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

您需要的是Hibernate查询缓存和org.hibernate.cacheable查询提示。或者,您可以启用Spring缓存,并使用@Cacheable@CachePlace注释。

 类似资料:
  • 问题内容: 我想在hibernate项目中使用二级缓存,但是我只对hibernate二级缓存了解一点,任何人都可以解释我应该如何在代码中使用它以及需要什么配置和.jar文件吗?我将这些设置设置为我的hibernate.cfg.xml文件 并添加这些jar文件, 我想知道我是否需要更改其他配置? 我怎么知道我的项目使用二级缓存? 如果只是设置此设置,hibernate将自动使用此设置,否则我必须在我

  • 问题内容: 我正在开发hibernate+ ehcache程序。 ehcache.xml 我在bean.xml中提到了ehcache 我在dao类中的调用方法是 输出为: 但是它在数据库中命中了两次。我在代码中没有发现任何错误。请向我建议为什么它在数据库中命中了两次。 问题答案: 我已经解决了我的问题。我需要添加 在域类中。

  • 问题内容: 我在应用程序中使用了Hibernate二级缓存,由于某些商业原因, 我无法再更改实体注释 。 在我的项目中,除了从Hibernate更改数据库之外,还存在其他未通过Hibernate的本机SQL。因此,从本地SQL更新数据库后,Hibernate二级缓存数据可能会过时。这就是为什么我要 禁用某些实体的二级缓存(以编程方式或更改注释的其他方式)。 提前致谢! 问题答案: 警告: 正如Je

  • 问题内容: 给定这种方法,这是否代表了一些过分的风格或语义上的假象: 显然,这与此处的Java教程不符。 但是,它很清楚,简洁,到目前为止,完全满足了我的需求。是否有一个令人信服的,务实的理由来创建局部变量,在每种情况下为其分配值,在每种情况下添加中断并在方法结束时返回该值? 问题答案: 将值分配给局部变量,然后最后返回该值被认为是一种好习惯。 也就是说,这就是该范例剩下的唯一优点。它起源于仅存在

  • 问题内容: 我试图在 POSTGRES中 编写一个复杂的查询,这个问题是该子查询。 这是我的表(id是主键和自动递增): 在此表中,我想获取id为“ xyz”且appid = 2的id,如果不存在,则插入并返回ID。 我知道有几个类似的问题,有些问的有些相同,我已经尝试过了,但似乎没有用。 这是我试图起诉的,但未能按预期进行: 当添加新元素并返回新添加元素的ID时,此方法效果很好,但当行已存在时不

  • 我正在实现一个基于实体属性值的持久化机制。所有数据库访问都是通过Hibernate完成的。我有一个包含节点路径的表,它非常简单,只有一个id和一个路径(字符串)。路径数量很少,大约几千条。 主表有数百万行,我没有重复路径,而是将路径规范化为它们自己的表。以下是我在插入主表时想要的行为 1)检查路径表中是否存在路径(通过实体管理器查询,使用路径值作为参数) 2) 如果不存在,则插入并获取id(通过实