Hibernate框架学习之二:深入理解持久化对象

前言

由于Hibernate框架是一个完全的ORM框架,所以在Hibernate开发中只涉及具体的对象与属性,所以对象在Hibernate中是很重要的方面。而持久化对象则与数据库中的记录息息相关了,可以简单把持久化类理解为普通的JavaBean,也被称为POJO(Plain Old Java Object),在Hibernate3中,持久化类的定义与普通JavaBean的定义基本一致,而不需要额外实现其他接口或者继承某个类。

但是使用要想是一个普通的POJO与数据库对应起来还需要映射的配置(这点后面会继续介绍)。持久化类的要求有以下几个:

  • 提供无参的构造方法
  • 提供一个对象表示属性,就是数据库中的主键(一般是id),在Hibernate中并没有强制要求对象表标识属性的数据类型,但是在开发中默认使用8种基本数据类型作为对象的表示属性。
  • 为属性提供set和get方法
  • 在必要的时候重写equals和hashCode方法。这里所谓必要的时候是指在需要把对象实例保存到集合对象中的时候。这种情况一般发生在映射的时候。我们知道重写这两个方法是为了对象标识符的比较,从而确定是否是同一个对象。

持久化对象的三种状态

下面是这三种状态的基本转换图:
Hibernate框架学习之二:深入理解持久化对象

下面对该图的转换过程进行简要的说明:

当创建有一个持久化对象的时候(使用new关键字),还不是持久态(Persistent State),这个时候因为还没有与具体的Session关联(运用JVM的相关的知识解释是没有GC Roots节点与该对象存在引用链关系),所以还是瞬时态(Transient State)。
这个对象与Session关联之后(可以理解为GC Roots节点就是Session对象),通过调用Session的save、persist等方法可以让一个瞬时态的对象转换为一个持久态的对象。一个持久态的对象在Session关闭后就会变为游离态(Detached State),这里可能有个疑问是,为什么Session关闭之后不是变为 瞬时态呢?因为处于游离态的对象是可以被新的Session重新持久化的。这点与瞬时态还是不同的,因为瞬时态的对象如果没有雨Session发生引用,那么只能被GC,而游离态的对象还有第二个选择。当然,如果游离态的对象仍然一直没有雨Session发生引用,那么也最终被JVM的垃圾回收机制GC的。
处于持久态的对象通过调用Session的evict或者clear方法(这这两个方法在Hibernate缓存策略中会使用到)会使得一个对象有持久太变为游离态。
注意到,上面还有一种删除态,在Hibernate官方中是没有这种状态的,这里只是为了表示对象被删除这个过程。

持久化状态改变的方法

通过上面的叙述,基本对象Hibernate对象的三种状态有了一个大体的认识,现在叙述改变对象的方法。

由上图可知,在一个对象被创建出来的时候,是瞬时态的。为了让一个对象变为持久态,可供调用的方法是:

  • Serializable save(Object obj):将obj变为持久态,并保存到数据库
  • Serializable save(Object obj,Object pk):在保存对象的时候指定主键,并保存到数据库中。会将对象变为持久态
  • void persist(Object obj):将对象持久化到数据库,没有返回值
  • void persist(Object obj,Object pk):在保存对象的时候指定主键,会把对象变为持久态

前面的save方法是Hibernate框架提供的,persist是JPA提供的,两者在使用上的区别在于:执行save方法的时候会产生一个返回值,这个时是对象的标识属性,执行persist方法是不会产生返回值的。此外,save方法在执行的时候会立即执行一条insert语句把对象保存到数据库中,而执行persist方法是不会的,在外部事务调用该方法的时候不会立即生成一条sql语句。因为在执行一个事务的时候往往是具有ACID性质的,如果立即生成sql语句则不能保证事务的原子性。