关于Hibernate缓存机制的一些澄清?

关于Hibernate缓存机制的一些澄清?,hibernate,Hibernate,我对在学习hibernate缓存教程时发现的语句有疑问 语句1:-一级缓存始终与会话对象关联。默认情况下,Hibernate使用此缓存 问题1:- 由于默认情况下,此缓存保存来自load、get等会话方法的所有结果。是否会因为保存seesion中的所有对象而成为主要内存问题? 问题2:- 我们是否需要在默认情况下启用此缓存或其位置?如果需要,我可以禁用一级缓存吗?如果是,怎么做 以下问题适用于一级缓存和二级缓存 问题3:- 如果我从缓存中获取相同的对象(假设我在同一个会话中两次加载custome

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

语句1:-一级缓存始终与会话对象关联。默认情况下,Hibernate使用此缓存

问题1:-
由于默认情况下,此缓存保存来自load、get等会话方法的所有结果。是否会因为保存seesion中的所有对象而成为主要内存问题?

问题2:-
我们是否需要在默认情况下启用此缓存或其位置?如果需要,我可以禁用一级缓存吗?如果是,怎么做

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

问题3:-
如果我从缓存中获取相同的对象(假设我在同一个会话中两次加载customerid为1的对象customer),那么从缓存返回的两个对象将与缓存中的对象具有不同的引用对吗?因为如果我更新customer对象中的某个字段,在调用save/update方法之前,它不应该反映在缓存中

问题4:-
根据我的理解,如果我们尝试从这个缓存中1秒从id获取customer对象,它将返回相同的旧对象,即使它在这段时间内得到了更新我们如何确保它是否得到更新,它从数据库中读取,而不是从缓存中读取?我想我们可以对类使用读写缓存策略,如EHCache

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

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

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

对吗?但不确定为什么查询缓存需要两个缓存区域?AFAIK
答案01:

Hibernate缓存加载的对象,以避免不必要的数据库访问。避免持久性上下文的最简单方法是使用
无状态会话
。无状态Hibernate会话没有脏检查责任,因此与不具有第一级缓存(持久性上下文)的需求相匹配

答案02:

  • 您不必启用一级缓存
  • 回答03

  • 如果一个对象在同一会话中使用其标识加载了两次,Hibernate将确保返回相同的对象,而不管是否启用了二级缓存。让我澄清一下,二级缓存不会缓存对象的实例。它维护实例的序列化(不完全)版本。 下面简要说明hibernate二级缓存的结构
  • 很抱歉,我无法理解“更新客户对象且其未反映在缓存中”背后的概念。我希望链接能澄清你的问题

    答案04

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

    EHCache为未更新的数据提供
    读写
    缓存策略 符合事务
    read committed
    保护的。这是避免,但不能帮助反对
  • 检查EHCache配置

    答案05:查询缓存

  • 查看这些链接以更好地了解会话缓存和查询缓存
    A.
    B.
    C

  • 这对查询缓存的结构进行了简单的解释


  • 希望这能有所帮助。

    感谢rictionlesspulley如此详尽的回答。我有以下问题。正如您所说的“让我澄清一下,二级缓存不会缓存对象的实例。它维护实例的序列化(不完全)版本”“我不明白你所说的cahe的序列化版本是什么意思?关于EH缓存,正如您所说,我们可以获得读取提交事务。这就是我所需要的。如果你转到答案05中的第二个链接,你将确切地看到对象是如何存储在二级缓存中的。我指的是*缓存对象*的序列化版本,而不是缓存本身。关于EHCache的读写缓存策略,请确保设置适当的缓存过期时间!