evict方法是从当前缓存中移除某个持久化实例.
flush作用是将数据库与缓存中的数据同步.
当flush后,这个持久化实例没有从缓存中移除,除非调用evict或者session.close();
在一个session线程中,如果存在多个insert,update,delete操作。Habernate会先把insert批量操作,然后是update,然后是delete。而不是按照我们代码的编写顺序进行执行。在某些情况下,这个特点会引起一些错误。
public void testFulsh_Evict1(){
Session session = HibernateUtils.getSession();
try {
session.beginTransaction();
Group group = new Group();
group.setName("猛牛集团");
session.save(group);
group.setName("蒙牛集团");
//update时不会发出sql语句,commit时才能发出sql
session.update(group);
//这里如果不用flush同步数据的,会接着执行下面的代码
//最后在commit之前才会走这一部,不符合我们的逻辑
session.flush();
User user =new User();
user.setName("牛根生");
user.setGroup(group);
session.save(user);
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
加入flush后,控制台输出的sql语句符合我们代码的流程:
Hibernate: insert into t_group (g_name) values (?)
Hibernate: update t_group set g_name=? where g_id=?
Hibernate: insert into t_user (u_name, u_group) values (?, ?)
使用uuid策略做主键时,例如insert一条记录,save完了,可以手动flush后evict。
使用native策略的主键时,save完后,可以直接手动evict,因为native主键策略下save自动完成了flush。
小常识:
所有的增删改操作,只要操作的是persistent状态的对象,数据库中有对应记录的,就不会在save、update、delete方法后马上执行sql语句,而是在commit时才执行所有的sql。
transistence对象在save的时候,主键生成策略只要不是依赖数据库生成的,在save的时候也不会发出sql语句,
uuid策略和assigned(手动分配)不是依赖数据库生成的,native是依赖数据库的。
相关链接:
http://apps.hi.baidu.com/share/detail/17203428