Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java hibernate中分离的、持久的和暂时的对象是什么?_Java_Hibernate_Orm - Fatal编程技术网

Java hibernate中分离的、持久的和暂时的对象是什么?

Java hibernate中分离的、持久的和暂时的对象是什么?,java,hibernate,orm,Java,Hibernate,Orm,hibernate中分离的、持久的和暂时的对象是什么?请举例说明。一个持久类的新实例,该实例与会话无关,在数据库中没有表示,并且Hibernate认为没有标识符值是暂时的 Person person = new Person(); person.setName("Foobar"); // person is in a transient state 持久性实例在数据库中有一个表示形式,一个标识符值,并与会话关联。通过将瞬态实例与会话关联,可以使其持久化: Long id = (Long) se

hibernate中分离的、持久的和暂时的对象是什么?请举例说明。

一个持久类的
新实例,该实例与
会话
无关,在数据库中没有表示,并且Hibernate认为没有标识符值是暂时的

Person person = new Person();
person.setName("Foobar");
// person is in a transient state
持久性实例在数据库中有一个表示形式,一个标识符值,并与
会话
关联。通过将瞬态实例与
会话关联,可以使其持久化:

Long id = (Long) session.save(person);
// person is now in a persistent state
现在,如果我们
关闭
Hibernate
会话
,持久实例将成为一个分离的实例:它不再附加到
会话
(但以后仍然可以修改并重新附加到新的
会话


所有这些都在Hibernate文档中得到了清楚的解释,我只是在上面解释一下。当然,这是必须阅读的。

除了已经确定的正确答案之外,持久、暂时、分离只是对象在hibernate中的状态


更准确地说,这三种状态实际上显示了hibernate对象的更改,并且hibernate中的会话生命周期状态对象具有以下状态:

瞬态-使用新操作符实例化的对象称为瞬态对象

如果一个对象刚刚使用new操作符实例化,并且它与Hibernate会话没有关联,那么它就是暂时的。它在数据库中没有持久表示,也没有分配标识符值。如果应用程序不再持有引用,则临时实例将被垃圾收集器销毁

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

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

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

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


让我也从垃圾收集器的角度解释一下

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

  • 瞬态
  • 持续状态
  • 分离状态
  • 最好通过一个代码示例来理解-

    让我们考虑一个POJO类作为学生对象->/P>

    Student student = new Student(); 
    
    现在,该学生对象处于瞬态状态


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

    session.save(student);
    
    现在,此POJO对象处于持续状态

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


    如果我们执行->

    session.beginTransaction.commit();
    
    session.evict(student); 
    
    然后POJO对象处于永久或数据库存储状态

    (垃圾收集器角度-GC无法清除此对象,因为此POJO对象现在不在JVM范围内,并且存储在 数据库中的表单表。所以我们可以说,这种数据库存储状态就像POJO对象的永久存储)


    如果我们执行->

    session.beginTransaction.commit();
    
    session.evict(student); 
    
    然后POJO对象被逐出或从持久状态移回分离状态


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

    给定以下实体:

    @Entity
    public class City {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)    
        private long id;
    
        // other fields and methods.
    }
    
    From(我还包括
    已删除的
    状态):

    瞬态

    该实体刚刚实例化,未与 持久性上下文。它在数据库中没有持久表示 数据库,通常未分配标识符值(除非 已使用指定的生成器)

    管理的或持久的

    该实体具有关联的标识符,并且与 持久性上下文。它可能会也可能不会实际存在于 数据库还没有

    分离的

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

    已删除

    该实体具有关联的标识符,并且与 持久性上下文,但已计划将其从 数据库


    注意:
    Hibernate API提供了多种方法来在实体状态之间切换,我认为值得探索一种方法。

    标识符值可能不是持久化对象的严格条件,因为我可以使用分配标识符生成策略。除了关闭在实例中读取的会话,可以通过调用session.execute()分离实例。这将使它不再由Hibernate管理(从而防止对实例的更改自动传播回数据库)。您可以通过session.update()将更改发送到数据库,并使用session.merge()重新附加它。我们很多时候都不遵循框架提供的原始文档。。有些时候,它本身就有隐藏的信息,只需要进行适当的描述就可以了。唯一的问题是我们不容易找到它:)
    持久实例有一个表示
    
    // city is in a detached state, Hibernate is no longer aware of the entity 
    session.evict(city)
    
    session.remove(city);