Hibernate 会话中持久对象的状态
Posted
技术标签:
【中文标题】Hibernate 会话中持久对象的状态【英文标题】:State of a persistent object in a Hibernate session 【发布时间】:2012-06-26 11:28:52 【问题描述】:我有一个关于 Hibernate 的可能非常简单的问题:
如果我有一个对象的持久化实例,并且其中一些对象的属性在同一个 Session
内进行了修改,这些更改对我来说也可见吗?
或者我必须refresh
对象才能获得它的当前状态?
我想扩展我的问题:如果这些更改不在同一个Session
内进行怎么办?如果它们是在Session
中制作的,由相同的SessionFactory
提供怎么办?
【问题讨论】:
【参考方案1】:如果您有一个实体加载了两次或更多次(不管是使用Query.list()
还是Session.load()
),那么您总是会得到相同的Java 对象实例。由于是同一个实例,因此无论您在何处使用此实例,都可以看到对该实例的每次修改,因此对于未持久化到数据库的修改也是如此(这是一定的危险)。
如果实体使用两个不同的会话加载两次(会话是否来自同一个 SessionFactory 无关紧要),那么您将获得 Java 类的两个实例。这两个实例是独立的。一个实例未获知另一实例中的修改。如果修改被持久化到数据库中,情况也不是这样。即使您再次加载实体并且它已经在会话缓存中,您也不会得到修改(例如:session1.load(entity); session2.save(entity); session1.load(entity);
然后session1
不会加载session2
所做的更改,因为实体已经在缓存)。如果直接在程序外部使用 SQL 进行修改,情况也是如此。要加载修改,您必须 evict()
实例或使用新会话。在这种情况下,建议使用版本化列(使用<version>
子句映射的列)以避免修改丢失。
【讨论】:
另一个极端情况是merge
:您可以拥有一个持久化实例,以及一个具有相同身份的非持久化(或分离?)实例,当您使用后者调用merge
时,它的任何变化都将在前者中变得可见。但是,非持久性实例本身并不持久,因此它不会显示任何未来的变化。正常使用是在合并后丢弃该实例并使用持久实例。【参考方案2】:
不需要刷新,除非它被分离,否则它将是可见的。
【讨论】:
以上是关于Hibernate 会话中持久对象的状态的主要内容,如果未能解决你的问题,请参考以下文章