实体对象的生命周期是Hibernate 应用中的一个关键概念。实体对象有三种状态:
1.瞬时状态(Transient)
刚用new语句创建,与数据库中的记录没有任何关联,也就是没有与其相关联的数据库记录 与Session没有任何关系,也就是没有通过Session对象的实例对其进行任何持久化的操作。
2.持久状态(Persistent)
已经被持久化,且加入到Session的缓存中。每个持久态对象都于一个Session对象关联,处于持久态的对象是于数据库中的记录相关联的,Hibernate会根据持久态对象的属性的变化而改变数据库中的相应记录。
3.游离状态(Detached)
游离态对象一定是由持久态对象转换而来。游离态实体不再于Session关联,游离态实体对象与数据库中的数据没有直接联系,主要表现在对其进行的修改不再影响到数据库中的数据,游离态实体对象在数据库中有相应的数据记录(如果该记录没有被删除)
三种状态之间的转换如图所示:
解析:
new 对象——>瞬时态
瞬时态—可通过update()、saveOrUpdate()等方法,转变成持久对象。
持久态—session.close/clear/evict—>游离态
持久态—session.delete—>瞬时态
游离态——session.save/session.saveOrUpdate/session.lock—>持久态
延迟加载机制:
当 Hibernate 从数据库中初始化某个持久化实体时,该实体的集合属性是否随持久化类一起初始化呢?如果集合属性里包含十万,甚至百万的记录,在初始化持久化实体的同时,完成所有集合属性的抓取,将导致性能急剧下降。完全有可能系统只需要使用持久化类集合属性中的部分记录,而完全不是集合属性的全部,这样,没有必要一次加载所有的集合属性。
对于集合属性,通常推荐使用延迟加载策略。所谓延迟加载就是等系统需要使用集合属性时才从数据库装载关联的数据。
默认情况下,Hibernate 也会采用延迟加载来加载关联实体,不管是一对多关联、还是一对一关联、多对多关联,Hibernate 默认都会采用延迟加载。
对于关联实体,可以将其分为两种情况:
- 关联实体是多个实体时(包括一对多、多对多):此时关联实体将以集合的形式存在,Hibernate 将使用 PersistentSet、PersistentList、PersistentMap、PersistentSortedMap、PersistentSortedSet 等集合来管理延迟加载的实体。这就是前面所介绍的情形。
- 关联实体是单个实体时(包括一对一、多对一):当 Hibernate 加载某个实体时,延迟的关联实体将是一个动态生成代理对象。
当关联实体是单个实体时,也就是使用 <many-to-one.../> 或 <one-to-one.../> 映射关联实体的情形,这两个元素也可通过 lazy 属性来指定延迟加载。