any - always save 永远保存
none - always update 永远更新
null - 当标识符是空的时候保存(默认情况)
valid identifier value (合法的标识符值)- 当标识符是null或者这个给定的值时保存
undefined - 对于version 或 timestamp来说的默认值。此时使用标识符检查。(原文: the default for version or timestamp, then identifier check is used.参见下文有进一步描述.)
// in the first session
Cat cat = (Cat) firstSession.load(Cat.class, catID);
// in a higher tier of the application
Cat mate = new Cat();
cat.setMate(mate);
// later, in a new session
secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)
secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)
saveOrUpdate()的用法和语义看来对初学者来说容易造成困惑。首先,如果你还没有试图在另一个新session中使用来自原session的实例,你根本就不需要使用update()或者saveOrUpdate()方法。有一些程序完全不需要使用这些方法。
通常,update()或saveorUpdate()方法在下列情形下使用:
程序在前面的session中装载了对象
对象被传递到UI(界面)层
对该对象进行了一些修改
对象被传递回业务层
应用程序在第二个session中调用update()保存修改
saveOrUpdate()完成了如下工作:
如果对象已经在这个session中持久化过了,什么都不用做
如果对象没有标识值,调用save()来保存它
如果对象的标识值与unsaved-value中的条件匹配,调用save()来保存它
如果对象使用了版本(version或timestamp),那么除非设置unsaved-value="undefined",版本检查会发生在标识符检查之前.
如果这个session中有另外一个对象具有同样的标识符,抛出一个异常
9.4.3. 把与Session脱离的对象重新绑定
lock()方法是用来让应用程序把一个未修改的对象重新关联到新session的方法。
//just reassociate: 直接重新关联
sess.lock(fritz, LockMode.NONE);
//do a version check, then reassociate: 进行版本检查后关联
sess.lock(izi, LockMode.READ);
//do a version check, using SELECT ... FOR UPDATE, then reassociate: 使用SELECT ... FOR UPDATE进行版本检查后关联
sess.lock(pk, LockMode.UPGRADE);
9.5. 删除持久化对象
使用Session.delete()会把对象的状态从数据库中移除。当然,你的应用程序可能仍然持有一个指向它的引用。所以,最好这样理解:delete()的用途是把一个持久化实例变成临时实例。
sess.delete(cat);
你可以通过传递给delete()一个Hibernate 查询字符串来一次性删除很多对象。
你现在可以用你喜欢的任何顺序删除对象,不用担心外键约束冲突。当然,如果你搞错了顺序,还是有可能引发在外键字段定义的NOT NULL约束冲突。
9.6. 同步(Flush)
每件隔一段时间,Session会执行一些必需的SQL语句来把内存中的对象和JDBC连接中的状态进行同步更新。这个过程被称为同步(flush),默认会在下面的时间点执行:
在某些find()或者iterate()调用的时候
在net.sf.hibernate.Transaction.commit()的时候
在Session.flush()的时候
涉及的SQL语句会按照下面的顺序安排:
所有对实体进行插入的语句,其顺序按照对象执行Session.save()的时间顺序
所有对实体进行更新的语句
所有进行集合删除的语句
所有对集合元素进行删除,更新或者插入的语句
所有进行集合插入的语句
所有对实体进行删除的语句,其顺序按照对象执行Session.delete()的时间顺序
(有一个例外时,如果对象使用native方式进行 ID 生成的话,它们一执行save就会被插入。)
除非你明确地发出了flush()指令,关于Session合时会执行这些JDBC调用是完全无法保证的,只能保证它们执行的前后顺序。当然,Hibernate保证,Session.find(..)绝对不会返回已经失效的数据,也不会返回错误数据。
也可以改变默认的设置,来让同步发生的不那么频繁。FlushMode类定义了三种不同的方式。大部分情况下,它们只由当你在处理“只读”的事务时才会使用,可能会得到一些(不是那么明显的)性能提高。
sess = sf.openSession();
Transaction tx = sess.beginTransaction();
sess.setFlushMode(FlushMode.COMMIT); //allow queries to return stale state
Cat izi = (Cat) sess.load(Cat.class, id);
izi.setName(iznizi);
// execute some queries....
sess.find("from Cat as cat left outer join cat.kittens kitten");
//change to izi is not flushed!
...
tx.commit(); //flush occurs
9.7. 结束一个Session
结束一个session包括四个独立的步骤:
清洗session
提交事务
关闭session
处理异常