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