Hbernate 与数据同步
1、hibernate的操作
http://wenku.baidu.com/view/c91a3f5c804d2b160b4ec033.html这里这篇文章很好。。先查看。
一般情况下:hibernate会把你add,update、delete这些操作封装session的actionQueue操作队列中,(此时没有提交到数据库),提交事务时候,他会去找session中actionQueue操作,他按照actionQueue中的集合一个一个找,先处理insersions,然后updatesions,最后deletesions。所以了,他不会按照你代码中save和update、deleta的顺序来进行数据上操作的。
执行完上述操作后,hibernate要清缓存(tx.commit()这个方法,他有进行了清除缓存的操作),此时,根据(进行add操作)insersions中的对象来设置,他会把该对象persistenceContext中session->persistenceContext->entityEntries->map-header的existsInDatabase=true。所以说,你如果在清除缓存之前把persistenceContext中的那个对象删除了(session.clear()),那他找不到对象,他就会抛异常了,所以你要注意了
2、项目中的一个例子分析
//message是struts2自动封装的一个对象
public void add(User sender, List<User> receivers, Message message) {
for(User receiver : receivers) {
message.setSender(sender);
message.setPostTime(new Date());
message.setReceiver(receiver);
message.setMsgType(0);
message.setIsRead(0);
/*
* 1、本处的model id生成策略是Identity
* 2、session在执行add语句之后,会提交一条insert数据库语句,插入数据库并返回数据库id
* 3、数据库级别设置成未提交读,就可以看到数据了(要用select语句,用工具刷新无法显示数据)
* 4、我们可以发现session的existsInDatabase=true,也说明了已经提交到数据中,并把session与数据库保持同步
* 5、existsInDatabase可以在session->persistenceContext->entityEntries->map-header中找到
* 6、跟踪dubeg发现session底下的actionQueue->insertions modcount会+1,说明他确实改变过(但都是null)
* 7、一般情况下,整个事务提交,需要清除缓存,此时session要根据insertions中的对象,来与数据库同步,也就是如果保存了就要把existsInDatabase=true
* 8、但是此处insertions都是为null。所以就不用再去设置existsInDatabase=true操作了
* 9、运行save这句话后message是处于持久态,persistneceContext存在这个对象,一旦你重新set***这个对象,Hibernate管理就会update数据库中的那个对象
* 10、所以你多次调用message,他也只认为你更新了原来的那个message(由于id一样,他最后还是只保存一个)
*
* */
this.messageDao.add(message);
/*
* 1、清除缓存,并把message从持久态拉出来变成了游离态,你可以发现运行clear之后,这个对象没有在persistenceContext出现过,但是你之前提交的那个message已经在数据中了
* 2、所以在clear之后再add,又一次把message放入持久态,但是他又重新获取了一个id号。所以他判断是新的一个对象来再一次插入数据库
*
*
*/
this.getHbernateDao().getSession().clear();
}
}
参考:
1、http://langhua9527.iteye.com/blog/343311
2、http://blog.csdn.net/wangzhuoyan/article/details/4201485