Hibernate 查询缓存 - 对于不在二级缓存中的对象 - 有风险吗?有用?不好的做法?

2023-11-26

与此相关question

Premise:

这些是我的假设,基于我的阅读、经验和理解,它们可能是错误的,如果是,请发表评论,我将编辑问题。

  • 查询缓存和二级缓存都很好
  • 查询缓存缓存查询+参数的标识符结果
  • 如果数据库发生更改,并且未反映到缓存中,则查询缓存存在风险

问题:

我有一个不在二级缓存中的对象。由于一些错误的编程或其他限制,加载对象的代码在同一个休眠会话中被多次调用。检索使用 HQL 查找查询 例如

 hibernateTemplate.find("from Foo f where f.bar > ?", bar);

在添加查询缓存之前,如果在同一个 Hibernate Session 内调用上述代码 N 次,则对数据库有 N 次命中

然后我想看看如果添加查询缓存会发生什么:

 Query query = session.createQuery("from Foo f where f.bar > ?");
 query.setCacheable(true);
 query.setParameter(bar);
 query.list();

当我添加查询缓存时,我注意到在同一个会话期间,hibernate 不再访问数据库 N 次,每个会话只访问一次。

  1. 所以我的第一个假设是 Hibernate 首先在会话缓存中搜索,然后在二级缓存中搜索。这个假设正确吗?
  2. 我还假设如果对象(Foo)不在二级缓存中,在数据库中更改,然后跨会话范围的查询缓存将返回错误的标识符,从而返回错误的对象。那是对的吗?
  3. 那么是否可以肯定地说,即使对于非 2L 缓存对象,使用查询缓存进行包含不可变信息的查询是一个好的实践? (例如,其 where 子句包含始终返回相同结果的条件的查询,例如“select p.ser_num where p.id = ?”,当 ser_num 和 id 对一旦创建后就不会更改)

顺便说一句,在相关question据称查询缓存不适用于会话缓存范围。我是否误解了这个说法,或者其他什么?


查询缓存是一种特殊类型的二级缓存。您所说的二级缓存我更愿意称之为“对象缓存”。

对你的假设的评论:

  • 查询缓存与二级缓存(又名对象 缓存)。

查询缓存仅将查询的原始结果保存为主键(用 Hibernate 的话说就是 id)。它不容纳实际的水合物体。这是有道理的,因为当您使用 jdbc 执行查询时,它实际上只会在您迭代 ResultSet 时返回水合(填充)对象。该说法不一定正确。如果查询非常复杂,因此需要很长时间才能运行,那么通过使用查询缓存可以节省时间。通过使用查询缓存,您不会节省从数据库加载对象所需的时间。

  • 如果数据库发生了变化,并且没有反映出来,查询缓存是有风险的 到缓存

这是事实,但它并不是查询缓存所独有的,对于您所说的二级缓存(但通常称为对象缓存)来说也是如此。

所以我的第一个假设是 Hibernate 首先在 会话缓存,然后在第二级 缓存。这个假设正确吗?

是的,加载对象时这就是行为。

我还假设如果对象 (Foo) 不在二级缓存中, 在数据库中被更改,然后 查询缓存,跨会话 范围内,将返回错误 标识符,因此错误 对象。那是对的吗?

是的,对象缓存和查询缓存都会受到影响。仅当数据库在未通过休眠状态进行更改时才需要关注。您可以通过设置查询缓存的超时来减轻这种影响。

那么可以安全地说使用 查询缓存,用于包含以下内容的查询 即使对于非 2L 也是不可变的信息 缓存对象,是一个好的做法吗? (例如,查询其 where 子句 包含一个永远存在的条件 返回相同的结果,例如“选择 p.ser_num 其中 p.id = ?” 当 ser_num 而且id情侣一次都不会变 创建)

对于这些类型的对象,没有理由不同时使用对象缓存和查询缓存。

是的,查询缓存在会话级别(即 1 级缓存)下不起作用。这就是为什么当您再次执行查询时它会再次访问数据库的原因。它不会将查询的结果(id 集)放入会话缓存中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate 查询缓存 - 对于不在二级缓存中的对象 - 有风险吗?有用?不好的做法? 的相关文章

随机推荐

  • 如何将 Rowversion 或 Timestamp SQL Server 数据类型从 SQLDataReader 读取到 C# 变量

    我有一个 SQL Server 2012 数据库 每个表都有一组审计字段 其中一个是名为 RowVer 的列 其数据类型为timestamp 与 一样rowversion 我很难读取 a 的值SqlDataReader到一个 C 对象 其属
  • 在 Docker 容器内运行 Docker:无法连接到 Docker 守护进程

    我创建了一个 Dockerfile 来在 Docker 中运行 Docker FROM ubuntu 16 04 RUN apt get update apt get install y apt transport https ca cer
  • 两个四元数之间的“距离”(或角度大小)?

    我想找到两个四元数之间的 距离 我所说的 距离 是指单个浮点数或整数 而不是另一个四元数 这就是区别 即inverse q1 q2 我想你可以称我想要的为 角幅度 物理对象从原始角度旋转得越远 我就需要对其施加越大的扭矩 我不明白四元数涉及
  • 如何将 ComboBox 的 SelectedItem 绑定到作为 ItemsSource 中项目的副本的对象?

    我正在将 MVVM 模式与 WPF 一起使用 并遇到了问题 我可以将其简化为以下内容 我有一个 CardType 模型 public class CardType public int Id get set public string Na
  • 重写 std:exception 的析构函数

    如果以下情况 则以下程序无法在 g 4 4 中编译 line 8被评论 为什么 看来当我重写时std exception构造函数 我也必须重写它的析构函数 这是什么原因呢 include
  • Scala 中的反函数

    Scala 有没有办法表达任何函数的反函数 例如 如果我有一个函数f像这样 x Int gt x 1 我希望能够编写一个反函数g like f x Int gt x not a valid scala syntax or x Int gt
  • 字符串连接在 SQLite 中不起作用

    我正在尝试执行 SQlite 替换函数 但在函数中使用另一个字段 select locationname p from location 在此片段中 结果是 0 的列表 我本来期望一个字符串 其中包含来自 locationname 的文本和
  • 为什么使用整数而不是长整型?

    我经常看到有关的问题Overflow错误与vba 我的问题是为什么使用integer变量声明而不是仅仅定义所有数值变量 不包括double等 作为long 除非您正在执行类似 for 循环的操作 您可以保证该值不会超过 32 767 限制
  • Windows 上的 Java:如何将文件删除到垃圾箱(使用 JNA)

    我根本没有 Windows API 的经验 所以请原谅我的无知 我想将文件删除到垃圾箱 如何使用JNA以及如何检测这是否不可能 例如 因为文件位于网络共享上 Use com sun jna platform FileUtils代替com s
  • 使用支持 WebGL 的浏览器查看 VRML 文件 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我有一个生成 VRML 1 0 文件的旧应用程序 我想构建一个基于 WebGL 的 Web 界面来显示这些 VRML 文件 有没有简单的方法可以做到
  • 具有 ngFor 元素的 ngModel 的动态 angular2 形式

    我正在尝试创建一个连接到 ngModel 的动态表单 它允许用户根据需要添加更多控件 如下图所示 表单的行为符合预期 但添加一组新控件时除外 因为它会删除先前输入的内容 尽管模型没有改变 我创建了这个plunkr为了展示我正在谈论的行为 这
  • Kerberos、委派以及如何正确执行此操作?

    我有两个独立的自制应用程序 需要在它们之间进行通信 一个是前端应用程序 实际上是 asp net 另一个是会计应用程序的后端接口 后端接口不是专门为此前端创建的 它是许多其他应用程序用来与我们的产品集成的通用接口 为了方便用户 我们希望在前
  • 离散余弦变换DCT实现C

    我试图在 C 中实现正向和反向离散余弦变换 DCT 代码是通过 dct 函数将单个输入像素块变换为变换矩阵 然后通过 idct 功能 请参阅随附的代码 我的 idct 输出是 244 116 244 116 等连续值 从 idct 值的外观
  • 使用 SDL 时未定义对 WinMain@16 的引用

    我在让一切正常工作方面遇到了很多麻烦 以便我可以开始在 Windows 上进行开发 而不是在 Linux 上进行开发 Linux 是我在编码时通常使用的系统 我在尝试编译 SDL 程序时遇到了一个相当奇怪的问题 一旦我包含 SDL 库 程序
  • php 如何查找用户来自的位置?

    简单的问题 how to find the location url where a user came from before accessing my page and how to find the location url wher
  • Android 中已弃用“java.lang.String”

    我写了这样的简单标签 private static final String TAG MainActivity 字符串已被弃用 有没有其他方法可以使用String 根据此评论java lang string 在 android studio
  • 如何使用leakcanary,如何将leakcanary添加为jar以使用.mk文件构建apk

    LeakCanary 是一个适用于 Android 和 Java 的内存泄漏检测库 金丝雀泄密 我的项目是基于android make文件系统 依赖于一些android内部接口和自定义方法 如何将 LeakCanary 作为库添加到我的应用
  • 在 Hive 中将字符串转换为时间戳

    我的 Hive 表中有以下时间戳字符串表示形式 20130502081559999 我需要将其转换为字符串 如下所示 2013 05 02 08 15 59 我尝试过以下操作 code gt gt gt result from unixti
  • 如何比较不区分大小写和不区分重音的字符串

    如何比较不区分大小写和不区分重音的字符串 好吧 这在 SQL Server 上很容易完成 不过我想在 C NET 4 5 1 上做同样的事情 我怎样才能以最正确的方式做到这一点 我的意思是这 3 个字符串在比较时应该返回相等 http ww
  • Hibernate 查询缓存 - 对于不在二级缓存中的对象 - 有风险吗?有用?不好的做法?

    与此相关question Premise 这些是我的假设 基于我的阅读 经验和理解 它们可能是错误的 如果是 请发表评论 我将编辑问题 查询缓存和二级缓存都很好 查询缓存缓存查询 参数的标识符结果 如果数据库发生更改 并且未反映到缓存中 则