hibernate - 关于 Hibernate 缓存机制的一些说明?

标签 hibernate

我对在学习 hibernate 缓存教程时发现的语句有疑问。

陈述1:-一级缓存始终与Session对象相关联。 Hibernate 默认使用这个缓存。

问题 1:-
因为此缓存默认保存来自 session 方法(如加载、获取等)的所有结果。是否会因为保存所有对象而成为主要内存问题?

问题 2:-
我们是否需要默认启用此缓存或它在那里?如果需要,我可以禁用一级缓存吗?如果是怎么办?

以下问题适用于一级和二级缓存

问题 3:-
如果我从缓存中获取相同的对象(假设我在同一 session 中两次加载 customerid 为 1 的对象 customer),从缓存返回的两个对象将具有与位于缓存中的对象不同的引用。 对吗?因为如果我更新客户对象中的某些字段,它不应该反射(reflect)在缓存中,除非调用保存/更新方法。

问题4:-
根据我的理解,如果我们尝试从该缓存中第二次从 id 获取客户对象,它将返回相同的旧对象,即使它在两者之间得到了更新。 我们如何确保它在更新时从数据库中读取,否则从缓存中读取?我想我们可以将读写缓存策略与类似 EHCache

的类一起使用

问题 5:- 关于查询缓存
我读到这个声明:-查询中的更新经常发生。因此,对于查询缓存,需要两个缓存区域。

用于存储结果。(仅缓存标识符值和值类型的结果)。 用于存储最近的更新。

我认为“查询中的更新经常发生”意味着我们通常会更改一些参数值,例如 select * from customer where custid=? 所以 id 将被更改对于不同的客户 ID。因此查询缓存将保留每个查询(连同参数)和每个查询返回的结果。

对吧?但是不确定为什么我们需要两个缓存区域来进行查询缓存?

最佳答案

据我所知
答案 01:

Hibernate 缓存加载的对象,以避免对数据库进行不必要的访问。避免持久性上下文的最简单方法是使用 StatelessSession。 Stateless Hibernate Session 没有脏检查责任,因此可以很好地满足您没有一级缓存(持久上下文)的要求。

答案 02:

  1. 您不必启用一级缓存

回答 03

  1. 如果一个对象使用其身份在同一 session 中加载两次,Hibernate 确保返回相同的对象,无论是否启用二级缓存。让我澄清一下,二级缓存不缓存对象的实例。它维护实例的序列化(不完全)版本。 以下link简要说明hibernate二级缓存的结构。

很抱歉,我无法理解“更新客户对象但未反射(reflect)在缓存中”背后的概念。我希望该链接能澄清您的问题。

回答 04

  1. 如果配置不正确,就会出现从缓存中获取过时数据的问题。 如果缓存上的过期时间尚未发生,将获取状态数据。可以使用 Session.evict() 执行驱逐,但是您可能不清楚需要驱逐哪些数据。因此,缓存应该始终是优化数据库访问的最后一步。 通过重新评估集合关系上的关联和获取计划,可以达到良好的优化水平,从而避免 N+1 选择问题,同时避免。

    EHCache 为不更新的数据提供读写缓存策略 符合事务read committed 保护。那就是避免dirty reads但不能帮助反对repeatable reads .

检查 EHCache 配置 here

答案 05:查询缓存

  1. 查看这些链接以更好地了解 session 缓存和查询缓存
    答:Session Cache
    B. Second Level Cache
    C. Query Cache

  2. Checkout this link其中对查询缓存的结构进行了简要/更简单的解释。

希望这对您有所帮助。

关于hibernate - 关于 Hibernate 缓存机制的一些说明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7488978/

相关文章:

java - Hibernate 中的延迟加载是什么?

java - 为什么 javax.money.CurrencyUnit 不可序列化?

触发了 hibernate 实体拦截器但设置值不保存

java - 使用标准时出现 hibernate 错误

java - 搜索包含所有特殊字符的数据库表

java - 集群环境中的 Hibernate session 缓存行为?

Hibernate:关于@GeneratedValue 工作原理的概述

java - Hibernate envers : RelationTargetAuditMode. NOT_AUDITED vs @NotAudited

java - Derby "A truncation error was encountered trying to shrink CLOB ' <流值 >' to length 255"

java - 验证期间未使用 Spring MessageSource