2017-04-04 46 views
0

我参考了一本关于java持久性和Hibernate的书。Hibernate用于脏检查的“状态快照”

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

该书反复提到“状态快照” - 用于其他检查脏检。

请参见:

持久化上下文高速缓存不会自动收缩。保持持久化上下文的大小为 。通常情况下,很多 持久实例在您的上下文中都是偶然的,例如 示例,因为您只需要几个项目,但需要查询很多项目。 极大图可能会对性能造成严重影响,并且 需要大量内存用于状态快照。检查你的 查询只返回你需要的数据,并考虑以下几种方式来控制Hibernate的缓存行为。

您可以调用EntityManager#detach(i)从持久化上下文手动驱逐持久实例 。您可以致电 EntityManager#clear()分离所有持久性实体实例, 让您留下空的持久性上下文。

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

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

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

item.setName("New Name");

em.flush();

我的问题,因此,是:

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

  • 我在哪里可以找到有关这些状态快照进一步资料?

编辑:考虑到Naros的答案,我发现会话类Hibernate文档中非常有趣的信息:Session#setDefaultReadOnly

更改加载到本次会议 的实体和代理默认从可修改模式到只读模式,或从可修改模式到只读 模式。只读实体不会被肮脏检查,并且不会维护持久状态的快照。只读实体可以修改为 ,但更改不会持久。初始化代理时, 装入的实体将具有与未初始化的代理具有的 相同的只读/可修改设置,而与会话的当前 设置无关。要更改只读/修改设置特定 实体或代理已在本次会议

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

回答

1

不同的是他们代表什么。加载到持久化上下文中的任何对象几乎总是加载一些状态快照,无论它们是标识符还是非惰性加载属性。

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

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

+0

非常感谢纳罗斯。你能否指点我的文档的相关部分,提到你已经解释了什么,或者更好地说明了负责管理状态快照的hibernate类的源代码? – balteo

+0

再次你好Naros。我找到了这些文档,并相应地编辑了我的文章。与状态快照相关的源代码链接对你来说将是非常棒的! – balteo