【问题标题】:"state snapshots" used by Hibernate for dirty checkingHibernate 用于脏检查的“状态快照”
【发布时间】:2017-04-04 12:19:15
【问题描述】:

我指的是一本关于 java 持久性和 Hibernate 的书。

(参见:https://www.manning.com/books/java-persistence-with-hibernate-second-edition)。

这本书反复提到“状态快照” - 用于脏检查。

见:

持久性上下文缓存永远不会自动收缩。保持 您的持久性上下文的大小到必要的最小值。很多时候,很多 你的上下文中的持久实例是偶然出现的——因为 例如,因为您只需要几个项目但查询了很多项目。 非常大的图表会产生严重的性能影响,并且 状态快照需要大量内存。检查您的 查询仅返回您需要的数据,并考虑以下方法 控制 Hibernate 的缓存行为。

你可以调用 EntityManager#detach(i) 来驱逐一个持久化实例 手动从持久性上下文中。你可以打电话 EntityManager#clear() 分离所有持久实体实例, 留下一个空的持久性上下文。

本机 Session API 有一些您可能会发现的额外操作 有用。您可以将整个持久性上下文设置为只读模式。 这会禁用状态快照和脏检查,而 Hibernate 不会 将修改写入数据库:

em.unwrap(Session.class).setDefaultReadOnly(true);

Item item = em.find(Item.class, ITEM_ID);

item.setName("New Name");

em.flush();

因此我的问题是:

  • Hibernate 从@Entity 类创建的代理对象与上面提到的状态快照有什么区别?

    李>
  • 我在哪里可以找到有关这些状态快照的更多文档?

编辑:考虑到 Naros 的回答,我在 Session 类的休眠文档中发现了非常有趣的信息:Session#setDefaultReadOnly

更改加载到此会话中的实体和代理的默认值 从可修改模式到只读模式,或从可修改模式到只读模式 模式。只读实体不进行脏检查和快照 不维护持久状态。只读实体可以是 已修改,但更改不会保留。初始化代理时, 加载的实体将具有相同的只读/可修改设置 未初始化的代理有,不管会话的当前 环境。更改特定的只读/可修改设置 已在此会话中的实体或代理

这里是链接:https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/Session.html#setDefaultReadOnly-boolean-

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:

    区别在于它们代表什么。加载到持久性上下文中的任何对象几乎总是加载一些状态快照,无论它们可能是标识符还是仅是非延迟加载的属性。

    当一个实体被加载到持久化上下文中时,该实体的数据库列的值将被存储在一个对象数组中,该数组被称为状态快照。它表示实体在数据库级别的状态,我们以后可以在用户在事务的整个生命周期中更改实体对象的状态时使用它,例如进行脏检查。

    另一方面,代理代表包装标识符的占位符。它确实维护了一些状态快照,通常是标识符,但它不是完整的数据库行,因此,脏检查不能也不会在代理实例上执行。

    【讨论】:

    • 非常感谢纳罗斯。能否请您指出文档的相关部分,其中提到了您所解释的内容,或者更好地指向负责管理状态快照的休眠类的源代码?
    • 你好,Naros。我找到了文档并相应地编辑了我的帖子。与状态快照相关的源代码链接会很棒!
    猜你喜欢
    • 1970-01-01
    • 2011-07-13
    • 2014-09-21
    • 2011-02-10
    • 1970-01-01
    • 2020-03-15
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多