lectery 2009-04-14 17:26
浏览 172
已采纳

被Hibernate的Session绊了一跤

写这篇博客的原因是出于昨天我在问答频道的一个问题,该问题如下:

 

    当在servlet中调用DAO的save方法并提交事务后,控制台显示已经执行了sql语句,但是却没有向数据库中记录,如果把数据库的隔离级别设置为未提交读,这是可以看见刚插入的记录,但是之前已经调用了提交事务的语句,这是为什么呢? 
注:主键生成策略为“native”,数据库是MySQL。
问题补充:
已经把数据库操作放到了事务中,而当第二条记录提交的时候才会向数据库中插入第一条记录,而新提交的记录不会被插入。
问题补充:

Java代码 ;
  1. UserDAO userDAO = new UserDAO();  
  2.         User user = new User();  
  3.           
  4.         SessionFactory sessionFactory = HibernateSessionFactory.getSessionFactory();  
  5.         Session session = sessionFactory.openSession();  
  6.         Transaction tx = null;  
  7.           
  8.         user.setUsername(registerForm.getUsername());  
  9.           
  10.         user.setEmail(registerForm.getEmail());  
  11.   
  12.         try {  
  13.             tx = session.beginTransaction();  
  14.             userDAO.save(user);  
  15.             tx.commit();  
  16.         }  
  17.         catch (RuntimeException e) {  
  18.             if (tx != null)  
  19.                 tx.rollback();  
  20.             throw e;   
  21.         }  
  22.         finally {  
  23.             session.close();  
  24.         }  

通过查看Hibernate的代码发现的其中的问题。
我在获得Session对象的时候采用的是 sessionFactory.openSession();  Hibernate会新产生一个Session对象,接着执行userDAO.save(user)语句,而UserDAO类的save方法中用到的Session是通过HibernateSessionFactory.getSession()方法获得的,再继续看HibernateSessionFactory,其getSession()方法如下
 public static Session getSession() throws HibernateException {
        Session session = (Session) threadLocal.get();

        if (session == null || !session.isOpen()) {
            if (sessionFactory == null) {
                rebuildSessionFactory();
            }
            session = (sessionFactory != null) ? sessionFactory.openSession()
                    : null;
            threadLocal.set(session);
        }

        return session;
    }
 因此HibernateSessionFactory会为每个线程创建一个Session对象,MyEclipse所生成的DAO类就是用的这个
Session,这与在程序中通过openSession()方法所得到的是两个不同的Session对象,因此我在程序中调用的提交事务方法是在后一个Session中进行的,而对User对象的保存是在第一个Session中,而该Session中并没有执行提交事务操作。
    但是,至于之前的为什么当我执行第二次插入操作时会把前一条记录插入的原因还没有弄清楚,哪位大哥知道,欢迎留言。


  • 写回答

1条回答 默认 最新

  • ww0901 2009-04-14 17:26
    关注

    数据库连接正常关闭时,如果没有事务提交语句,在关闭之前的DML操作会自动提交事务。ORACLE就是这样。

    楼主可以具体检查一下当前MySQL的事务引擎是怎么设置的,或者直接在数据库命令行下插入一条记录,然后正常退出数据库,再检查数据库中是否插入了数据。。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?