`

(学习笔记)Hibernate 保存问题机制

 
阅读更多

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

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics