当应用程序通过new语句创建了一个对象,这个对象的生命周期就开始了,当不再有任何引用变量引用它,这个对象就结束生命周期,它占用的内存就可以被JVM的垃圾回收器回收。对于需要被持久化的POJO对象,在它的生命周期中,可处于以下三个状态之一:
(1) 临时状态(transient)
刚刚用new创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。
(2) 持久化状态(persistent)
已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。
(3) 游离状态(detached)
已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对象。
图为Java对象的完整状态转换图,Session的特定方法触发Java对象由一个状态转换到另一个状态。从图中看出,当Java 对象处于临时状态或游离状态,只要不被任何变量引用,就会结束生命周期,它占用的内存就可以被JVM的垃圾回收器回收;当处于持久化状态,由于 Session的缓存会引用它,因此它始终处于生命周期中。
临时对象特征
(1) 不处于Session的缓存中,也可以说,不被任何一个Session实例关联。
(2) 在数据库中没有对应的记录。
在以下情况下,Java对象进入临时状态:
(1) 当通过new语句刚创建一个Java对象,它处于临时状态,此时不和数据库中的任何记录对应
(2) Session的delete()方法能使一个持久化对象或游离对象转变为临时对象。对于游离对象,delete()方法从数据库中删除与它对应的记录; 对于持久化对象,delete()方法从数据库中删除与它对应的记录,并且把它从Session的缓存中删除。
持久化对象的特征
(1) 位于一个Session实例的缓存中,也可以说,持久化对象总是被一个Session实例关联。
(2) 持久化对象和数据库中的相关记录对应。
(3) Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库。
Session的许多方法都能够触发Java对象进入持久化状态:
(1) Session的save()方法把临时对象转变为持久化对象。
(2) Session的load()或get()方法返回的对象总是处于持久化状态。
(3) Session的find()方法返回的List集合中存放的都是持久化对象。
(4) Session的update()、saveOrUpdate()和lock()方法使游离对象转变为持久化对象。
(5)当一个持久化对象关联一个临时对象,在允许级联保存的情况下,Session在清理缓存时会把这个临时对象也转变为持久化对象。
Hibernate保证在同一个Session实例的缓存中,数据库表中的每条记录只对应惟一的持久化对象。例如对于以下代码,共创建了两个 Session实例:session1和session2。session1和session2拥有各自的缓存。在session1的缓存中,只会有惟一 的OID为1的Customer持久化对象,在session2的缓存中,也只会有惟一的OID为1的Customer持久化对象。因此在内存中共有两个 Customer持久化对象,一个属于session1的缓存,一个属于session2的缓存。引用变量a和b都引用session1缓存中的 Customer持久化对象,而引用变量c引用session2缓存中的Customer持久化对象:
Session session1=sessionFactory.openSession(); Session session2=sessionFactory.openSession(); Transaction tx1 = session1.beginTransaction(); Transaction tx2 = session2.beginTransaction(); Customer a=(Customer)session1.load(Customer.class,new Long(1)); Customer b=(Customer)session1.load(Customer.class,new Long(1)); Customer c=(Customer)session2.load(Customer.class,new Long(1)); System.out.println(a= =b); //true System.out.println(a= =c); //false tx1.commit(); tx2.commit(); session1.close(); session2.close();
Java对象的持久化状态是相对于某个具体的Session实例的,以下代码试图使一个Java对象同时被两个Session实例关联:
Session session1=sessionFactory.openSession(); Session session2=sessionFactory.openSession(); Transaction tx1 = session1.beginTransaction(); Transaction tx2 = session2.beginTransaction(); Customer c=(Customer)session1.load(Customer.class,new Long(1)); //Customer对象被session1关联 session2.update(c); //Customer对象被session2关联 c.setName("Jack"); //修改Customer对象的属性 tx1.commit(); //执行update语句 tx2.commit(); //执行update语句 session1.close(); session2.close();
当执行session1的load()方法时,OID为1的Customer对象被加入到session1的缓存中,因此它是 session1的持久化对象,此时它还没有被session2关联,因此相对于session2,它处于游离状态。当执行session2的 update()方法时,Customer对象被加入到session2的缓存中,因此也成为session2的持久化对象。接下来修改Customer 对象的name属性,会导致两个Session实例在清理各自的缓存时,都执行相同的update语句:
update CUSTOMERS set NAME='Jack' …… where ID=1;
在实际应用程序中,应该避免一个Java对象同时被多个Session实例关联,因为这会导致重复执行SQL语句,并且极容易出现一些并发问题。
游离对象的特征
(1) 不再位于Session的缓存中,也可以说,游离对象不被Session关联。
(2) 游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录(前提条件是没有其他程序删除了这条记录)。
游离对象与临时对象的相同之处在于,两者都不被Session关联,因此Hibernate不会保证它们的属性变化与数据库保持同步。游离对象与临时对象的区别在于:前者是由持久化对象转变过来的,因此可能在数据库中还存在对应的记录,而后者在数据库中没有对应的记录。
Session的以下方法使持久化对象转变为游离对象:
(1) 当调用Session的close()方法时,Session的缓存被清空,缓存中的所有持久化对象都变为游离对象。如果在应用程序中没有引用变量引用这些游离对象,它们就会结束生命周期。
(2)Session的evict()方法能够从缓存中删除一个持久化对象,使它变为游离状态。当Session的缓存中保存了大量的持久化对象,会消耗许多内存空间,为了提高性能,可以考虑调用evict()方法,从缓存中删除一些持久化对象。但是多数情况下不推荐使用evict()方法,而应该通过查询语言,或者显式的导航来控制对象图的深度。
相关推荐
通过持久化,我们可以将应用程序中的对象状态保存到数据库中,以便在后续的使用中能恢复这些状态,而无需每次都需要重新从数据库查询。这提高了效率,减少了对数据库的直接操作,有助于降低系统复杂性。 ORM(对象...
- **用途**:当需要将数据库中的数据转换为Java对象以便于处理时,就会使用到PO。 - **特点**: - 与数据库表结构相对应; - 不包含任何业务逻辑或数据操作行为。 #### 二、VO:Value Object(值对象) 值对象...
**状态转换示例** - 创建一个新的User对象并设置属性,此时对象处于Transient状态。 - 通过Session的beginTransaction()和save()方法,对象进入Persistent状态,其变更会被保存到数据库。 - 当Session关闭,User...
六、实体状态转换 当创建一个新的实体对象并调用Session的save或saveOrUpdate方法时,对象从Transient状态转变为Persistent状态。如果在事务中对Persistent对象进行修改,然后提交事务,修改会持久化到数据库。当...
2. **对象状态**:Hibernate管理的对象具有三种状态:瞬时态(Transient)、持久态(Persistent)和脱管态(Detached),它们的状态转换由Hibernate的Session负责。 3. **JMX集成**:允许通过JMX(Java Management ...
Tuplizer 是 Hibernate 中用于将 ResultSet 转换为 Java 对象的组件,它提供了更多的灵活性和控制能力。 #### 七、基本的 ORM 映射 **5.1 映射声明** - **5.1.1 文档类型** Hibernate 映射文件遵循一定的文档...
- 对象持久化:将对象状态保存到数据库中。 - ORM:对象关系映射,用于将对象模型转换为关系模型。 - POJO:普通Java对象,符合Java Bean规范。 - Hibernate:ORM框架,基于JDBC,通过XML配置文件管理数据库连接...
### 深入理解持久化对象 #### Hibernate与持久化对象 Hibernate作为一款优秀的Java持久层框架,其设计理念强调低侵入性,这意味着...理解和掌握持久化对象的状态转换及修改方法,对于高效使用Hibernate框架至关重要。
- **实例状态**:解释了 Hibernate 管理的实体对象可能存在的几种状态(瞬时态、持久态、托管态),以及状态之间的转换机制。 - **JMX 集成**:介绍如何通过 JMX 监控 Hibernate 的运行状况。 - **JCA 支持**:说明...
持久化是Hibernate中的关键概念,它是指将Java对象的状态保存到数据库中,使得即使程序关闭后,这些对象的状态也能被恢复。ORM框架如Hibernate通过映射机制实现了对象与数据库表之间的转换。ORM的优势在于提高了开发...
- **Hibernate对象状态**: 介绍了瞬态、持久、游离等状态。 - **使对象持久**: 如何将对象变为持久状态。 - **加载一个对象**: 使用不同的方法加载持久化对象。 - **查询**: 使用HQL或其他查询语言执行复杂查询。
4. **会话(Session)**:Hibernate的会话是与数据库交互的主要接口,用于管理对象的状态。它提供了一种事务性的边界,并且可以实现透明的缓存。 5. **查询语言(HQL)**:Hibernate Query Language,类似于SQL,但...
- **实例状态**:包括瞬态、持久化和脱管三种状态,用于描述实体对象在 Session 中的不同状态。 - **JMX 集成**:提供 Java 管理扩展支持,允许远程监控和管理 Hibernate 运行时状态。 - **JCA 支持**:支持 Java ...
- **unsaved-value**: Hibernate中的一种特殊值,用于标识未保存的对象状态。 ##### 9. 事务管理 - **基于JDBC的事务管理**: - 使用Connection对象的commit()和rollback()方法控制事务。 - **基于JTA的事务管理**...
- **ORM映射**:Hibernate提供了一种对象关系映射机制,使POJO能够与数据库表自动映射。 - **缓存管理**:通过Hibernate的缓存机制提高应用程序性能。 **领域驱动设计(DDD)**: 领域驱动设计是一种软件开发方法...