saveOrUpdate方法是分为save(insert)和update(update)方法,它是根据session中对象的状态来判断并选择执行操作的。下面简述hibernate中对象的三种状态。
瞬时态(Transient,临时态):(对象未被持久化)实例对象是通过new关键字来开辟内存空间创建java对象,但是它并没有纳入hibernate的session管理中,如果没有变量对它引用,它将被JVM(垃圾回收器)回收。瞬时状态的对象在内存中是孤立存在的,它与数据库中的数据无任何关联,仅是一个信息携带的载体。假如一个瞬时状态对象被持久状态对象引用,那么它就会自动转换为持久化对象。它的生命周期由JVM管理
持久态(Persistent):(对象被持久化)持久化状态对象存在与数据库中的数据关联,它总是与会话状态(Session)和事务(Transaction)关联在一起。当持久化状态对象发生改动时并不会立即执行数据库操作,只有当事务结束时,才会更新数据库,以便保证Hibernate的持久化对象和数据库操作的同步性当持久化状态对象变为脱管状态对象时,它将不在hibernate持久层的管理范围之内。它的生命周期由session管理
脱管态(Detached,游离态):(对象曾被持久化,但是现在和session已经detached)当持久化状态的对象的Session关闭之后,这个对象就从持久化状态的对象变为脱管状态的对象。托管状态的对象仍然存在与数据库中的数据关联,只是它并不在hibernate的session管理范围之内。如果将脱管状态的对象重新关联某个新的Session上,它将变回持久化状态对象。=》这被称作跨session进行状态维护。
当表单提交后,调用saveOrUpdate方法,如果为瞬时态对象,调用save方法,执行insert操作;如果为脱管态对象,则调用update方法,执行update操作。那么判断对象是瞬时态还是脱管态的方法如下:
(1)Java对象的OID(Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系。对象的OID和数据库的表的主键对应。)取值为null
(2)Java对象具有version属性并且取值为null
(3)在映射文件中为元素设置了unsaved-value属性,并且OID取值与unsaved-value属性只匹配
(4)在映射文件中为version属性设置了unsaved-value属性,并且version属性取值与unsaved-value属性值匹配
(5)自定义了Hibernate的Interceptor实现类,并且Interceptor的isUnsaved()方法返回Boolean.TRUE