"状态快照" Hibernate用于脏检查

时间:2017-04-04 12:19:16

标签: hibernate jpa

我参考了一本关于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类创建的代理对象与上面提到的状态快照有什么区别?

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

编辑:考虑到纳罗斯的回答,我在会话类的hibernate文档中发现了非常有趣的信息:Session#setDefaultReadOnly

  

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

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

1 个答案:

答案 0 :(得分:2)

不同之处在于他们所代表的。加载到持久性上下文中的任何对象几乎总是加载一些状态快照,无论它们可能是标识符还是只是非延迟加载的属性。

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

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