session flush方法主要做了两件事:
* 清理缓存
* 执行sql语句
session 在什么情况下执行flush
*默认在事务提交时
*显示的调用flush
*在执行查询前,如:iterate
public void save(){
Session session=null;
Transaction tr=null;
try{
session=HibernateUtil.getSession();
tr=session.beginTransaction();
Client client=new Client();
client.setUserName("吴海东");
client.setUserPass("1111");
client.setCreateDate(new Date());
//因为client的主键生成策略采用的是uuid,所以调用完成save后,只是将client纳入到了session管理
//不会发出insert语句,但是id已经生成了,session中existsInDatebase状态为false
session.save(client);
//调用flush,hibernate会清理缓存,执行sql,
//如果数据库的隔离级别设置为未提交读,那么我们可以看到flush过的数据
//并且session中existsInDatebase状态为true
session.flush();
//提交事务
//默认情况下commit操作会先执行flush清理缓存,所以不用显示的调用flush
//commit后数据时无法回滚的
tr.commit();
}catch(Exception e){
e.printStackTrace();
tr.rollback();
throw new RuntimeException();
}finally{
HibernateUtil.closeSession(session);
}
}
public void save1(){
Session session=null;
Transaction tr=null;
try{
session=HibernateUtil.getSession();
tr=session.beginTransaction();
Client client=new Client();
client.setUserName("BBB");
client.setUserPass("1111");
client.setCreateDate(new Date());
//因为client的主键生成策略为native,所以调用session.save后,执行insert语句,返回有数据库生成的Id
//纳入session的管理,修改了session中existsInDatebase状态为true
//如果数据库的隔离级别设置为未提交读,那么我们可以看到save过的数据
session.save(client);
tr.commit();
}catch(Exception e){
e.printStackTrace();
tr.rollback();
throw new RuntimeException();
}finally{
HibernateUtil.closeSession(session);
}
}
public void save2(){
Session session=null;
Transaction tr=null;
try{
session=HibernateUtil.getSession();
tr=session.beginTransaction();
Client client=new Client();
client.setUserName("CCC");
client.setUserPass("1111");
client.setCreateDate(new Date());
//因为client的主键生成策略采用的是uuid,所以调用完成save后,只是将client纳入到了session管理
//不会发出insert语句,但是id已经生成了,session中existsInDatebase状态为false
session.save(client);
//将client对象从session中逐出,即sessiond的EntiryEntries属性中逐出
session.evict(client);
//无法成功提交,因为hibernate在清理缓存时,在session的insertions集合中取出client对象进行insert语句
//需要更新entityEntries属性中的existsInDatabase为true,而我们采用evict已经将client从session中逐出
//所以找不到相关数据,无法更新,抛出异常
tr.commit();
}catch(Exception e){
e.printStackTrace();
tr.rollback();
throw new RuntimeException();
}finally{
HibernateUtil.closeSession(session);
}
}
save2()方法中的错误的解决方法!
在eviet()方法之前执行先执行flush()方法
flush():flush后hibernate会清理缓存,会将client对象保存到数据库中,将session中的insertions中的client清除,并且设置session中existsInDatabase的状态为true