4 Hibernate持久化对象状态
4.1 Entity states
Hibernate 官方文档:Chapter 3. Persistence Contexts
4.1.1 临时对象(New or Transient):
- 在使用代理主键的情况下, OID 通常为 null
- 不处于 Session 的缓存中
- 在数据库中没有对应的记录
new, or transient(['trænzɪənt] adj. 短暂的;路过的) - the entity has just been instantiated([ɪn'stænʃɪeɪt] v. 实例化(instantiate的过去分词);具现化,实体化) and is not associated with a persistence context. It has no persistent representation in the database and no identifier value has been assigned.
4.1.2 持久化对象(Managed or Persistent):
- OID 不为 null(has an associated identifier)
- 位于 Session 缓存中
- 若在数据库中已经有和其对应的记录(associated with a persistence context), 持久化对象和数据库中的相关记录对应
- Session 在 flush 缓存时, 会根据持久化对象的属性变化, 来同步更新数据库
- 在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象
managed, or persistent([pə'sɪst(ə)nt] adj. 固执的,坚持的;持久稳固的) - the entity has an associated identifier and is associated with a persistence context.
4.1.3 游离对象(Detached):
- OID 不为 null
- 不再处于 Session 缓存中
- 一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录
detached([dɪ'tætʃt] adj. 分离的,分开的;超然的) - the entity has an associated identifier, but is no longer associated with a persistence context (usually because the persistence context was closed or the instance was evicted(evict [ɪ'vɪkt] vt. 驱逐;逐出) from the context)
4.1.4 删除对象(Removed):
- 在数据库中没有和其 OID 对应的记录
- 不再处于 Session 缓存中
- 一般情况下, 应用程序不该再使用被删除的对象
removed - the entity has an associated identifier and is associated with a persistence context, however it is scheduled for removal from the database.
4.2 Making entities persistent
将一个对象从临时状态转换为持久化状态: session.save(); session.persist();
Once you've created a new entity instance (using the standard new operator) it is in new state. You can make it persistent by associating it to either a org.hibernate.Session or javax.persistence.EntityManager
Emp emp = new Emp();
emp.setEname("wangWu");
emp.setHiredate(new Date());
emp.setComm(10000L);
emp.setSal(10000L);
emp.setJob("MANAGER");
emp.setMgr(null);
//emp.setEmpno(10000L); //在save方法执行之前,为对象设置ID是无效的(该条语句无任何作用)
session.save(emp);
//emp.setEmpno(10000L); //在save方法执行之后,持久化对象的ID是不能被修改的(该条语句会抛出一个异常)
persist方法与save方法的区别:
- 在persist方法执行之前,若对象已经有id了,则不会执行INSERT方法,相反会抛出一个异常PersistentObjectException
4.3 session的get与load方法
从数据库中加载数据: session.load(); session.get();
load方法与get方法的区别:
-
- 执行get方法会立即加载对象,而执行load方法,若不使用该对象,则不会立即执行查询操作,而是返回一个代理对象
- load是延迟检索
- get是立即检索
-
- 若数据库中没有对应的记录,且SESSION也没有被关闭,同时需要使用对象时
- get返回null
- load直接抛出异常(但是如果没有使用该对象的任何属性(没有打印),没问题;若需要初始化会抛出异常)
-
- load方法可能会抛出LazyInitializationException异常 :
- 在需要初始化代理对象之前已经关闭了SESSION(在打印EMP对象之前关闭SESSION,get方法不会抛出异常(已经加载完毕),load方法会抛出异常)。
4.4 session的update方法
session.update()
- 若操作的是一个持久化对象,不需要显式调用update方法
- 若操作的是一个若操作的是一个游离对象,需要使用update方法将对象从游离状态转换为持久化状态
- 关闭并重新打开session将会清空session缓存,同样会使session从持久化状态转换为游离状态
- 无论更新的游离对象与数据表中的数据是否一致,都会发送UPDATE语句,可以通过配置文件来修改
4.5 session的saveOrUpdate方法
session.saveOrUpdate()方法:
- 如果对象是一个游离对象,那么将会执行update(发送update语句)方法,如果是一个临时对象,将会执行save(发送insert语句)方法
- 如何判断一个对象为临时对象?
- java对象的OID为NULL
- 映射文件中的id列的unsaved-value元素指定的值与对象的OID一致,那么也认为该对象为临时对象
- 若OID不为空,但是数据表中还没有和其对应的记录,会抛出异常
- 了解:OID值为id的unsaved-value对象,也被认为是一个游离对象
4.6 session的delete方法
session.delete()
- 执行删除操作:只要OID和数据库表中的一条记录对应,就会准备执行DELETE方法
- 若OID在数据表中没有记录的数据,则抛出异常
4.7 session的evict()方法
session.evict()方法:从session缓存中将指定的对象移除
4.8 使用session获取JDBC的Connection
@Test
public void testDoWork(){
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
logger.info(connection);
}
});
}
更多
相关笔记:《Hibernate学习》阅读笔记
注意:本文归作者所有,未经作者允许,不得转载