休眠中哪些是分离的,持久的和短暂的对象?


100

休眠中哪些是分离的,持久的和短暂的对象?请举例说明。


在session.close上,是否会删除在会话范围内持久存在的所有对象?
Jigar Joshi

是的,它将删除,因此每当您关闭会话时,对象的持久状态都将转换为“分离”状态。
雷切尔

@Rachel很好的链接提供了用于更深入理解的代码
Priyank Thakkar

Answers:


161

new其不与相关联的永久类的实例Session,有在数据库中没有表示和没有标识符值被认为是瞬时的休眠:

Person person = new Person();
person.setName("Foobar");
// person is in a transient state

持久实例具有在数据库中的表示,标识符值,并与一个相关联Session。您可以通过将瞬态实例与关联来使其持久化Session

Long id = (Long) session.save(person);
// person is now in a persistent state

现在,如果我们使用close了Hibernate Session,则持久化实例将成为一个分离的实例:它不再附加到实例上Session(但是仍然可以修改并在Session以后重新附加到新实例上)。

在整个第10章中,所有这些内容都得到了清晰的解释。使用 Hibernate文档的对象,上面只是我的解释。绝对是必读的。


标识符值可能不是对象持久化的严格条件,因为我可以使用分配的标识符生成策略。
Abhijeet Kashnia,2010年

除了关闭在实例中读取的会话外,还可以通过调用session.evict()来分离实例。这使它脱离了Hibernate的管理(从而防止了对实例的更改自动传播回db)。您可以通过session.update()将更改发送到数据库,然后使用session.merge()重新附加它。
Mooshu

1
我们很多时候不遵循框架提供的原始文档。.有时它本身具有隐藏的信息,只需要进行适当的描述即可探索。唯一的问题是我们不容易找到它:)
agpt 2014年

A persistent instance has a representation in the database提交保存操作之前,持久性实体在数据库中没有任何表示形式。
O.Badr

1
因此,分离的和短暂的实体差异是ID的存在吗?如果我创建具有分配的ID的新实例,那么它在形式上是暂时的,因为它尚未持久化,但由于具有ID,因此无法与分离实例区分开。对?
Ruslan Stelmachenko

9

休眠中的对象具有以下状态:

瞬态-使用new运算符实例化的对象称为瞬态对象。

如果对象只是使用new运算符实例化的,则该对象是瞬态的,并且该对象未与Hibernate Session关联。它在数据库中没有持久性表示形式,也没有分配标识符值。如果应用程序不再拥有引用,则临时实例将被垃圾回收器破坏。

持久性-具有与其关联的数据库标识的对象称为持久性对象。

持久实例具有数据库中的表示形式和标识符值。它可能只是被保存或加载;但是,根据定义,它属于会话的范围。当工作单元完成时,Hibernate将检测对处于持久状态的对象所做的任何更改,并将该状态与数据库同步。

分离的-分离的实例是一个已持久的对象,但其会话已关闭。

分离的实例可以在以后的时间点重新附加到新的Session,使其再次持久化。此功能为需要用户思考时间的长时间运行的工作单元启用了编程模型。我们称它们为应用程序事务,即从用户角度来看的一个工作单元。

http://webiwip.com/interview-questions-answers/hibernate-interview-questions/32012


5

让我也从垃圾收集器的角度进行解释。

休眠的对象状态有3种(或)休眠的对象范围-

  1. 暂态
  2. 持续状态
  3. 分离状态

最好通过代码示例来理解-

让我们将POJO类视为Student Object->

Student student = new Student(); 

现在,这个学生对象处于瞬态


当我们将此POJO对象附加到休眠会话时->

session.save(student);

现在,此POJO对象处于持久状态

(垃圾收集器的观点-GC无法清除处于持久状态的任何对象。因此,我们可以说持久状态就像POJO对象的临时存储


如果我们执行->

session.beginTransaction.commit();

则POJO对象处于永久或数据库存储状态

(垃圾收集器的观点-GC无法清除此对象,因为此POJO对象现在不在JVM的范围内并存储在数据库内的表单表中。可以说这个数据库存储状态类似于POJO的永久存储对象


如果我们执行->

session.evict(student); 

然后POJO对象被逐出或从持久状态移回分离状态。这样POJO对象的状态就是分离状态

(垃圾收集器的观点-GC可以轻松清除JVM中分离的状态POJO对象)


2

给定以下实体:

@Entity
public class City {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)    
    private long id;

    // other fields and methods.
}

Hibernate 5.2文档中(我也包括了removed状态):

短暂的

该实体刚刚被实例化,并且与持久性上下文无关。它在数据库中没有持久性表示形式,并且通常没有分配标识符值(除非使用了分配的生成器)。

City city = new City();

管理的或持久的

该实体具有关联的标识符,并且与持久性上下文关联。它可能已经存在,也可能尚未物理存在于数据库中。

// city will be in a managed/persistent state and any changes to it, will be tracked by hibernate
// and reflected to the database when the persistence context is flushed.
session.save(city);

超脱

实体具有关联的标识符,但不再与持久性上下文关联(通常是因为持久性上下文已关闭或实例已从上下文中退出)

// city is in a detached state, Hibernate is no longer aware of the entity 
session.evict(city)

已移除

该实体具有关联的标识符,并且与持久性上下文关联,但是已安排将其从数据库中删除。

session.remove(city);


注意: Hibernate API提供了几种在实体状态之间切换的方法,我认为值得探索Hibernate Session类


0

除了已经确定的正确答案之外,持久,短暂,分离只是对象处于休眠状态。

更准确地说,这三种状态实际上显示了休眠对象的更改和会话生命周期状态

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.