HibernateDaoSupport,事务没有回滚

时间:2011-01-26 21:45:43

标签: java hibernate spring

我正在使用Spring + Hibernate和PostgreSQL进行一些“手动”事务管理 在转向基于aop的事务管理之前,我想尝试一下并了解其工作原理。

@Repository
public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {

    @Override
    public void saveUser(User u) {
        Transaction tx = getSession().beginTransaction();
        getHibernateTemplate().saveOrUpdate(u);
        tx.rollback();

    }
}

在这里调用saveUser,我假设保存一个新用户将被回滚。 但是,移动到psql命令行后,用户将保存在表中。

为什么不回滚,我需要配置什么才能以这种方式进行交易?

编辑;多一点调试似乎表明getHibernateTemplate()使用的不同于getSession()返回的会话(?)

将代码更改为

Transaction tx = getSession().beginTransaction();
getSession().persist(u);
tx.rollback();

并且事务确实被回滚。但我仍然不明白为什么hibernateTemplate会使用/创建一个新的会话..

2 个答案:

答案 0 :(得分:2)

有几种可能性浮现在脑海中(没有双关语意图):

a)您的JDBC驱动程序默认为autocommit = true,并以某种方式忽略beginTransaction()和rollback()调用;

b)如果您正在使用Spring 3,我相信 SessionFactory.getSession()返回由Spring代理包装的Hibernate Session对象。在Session上设置Spring代理部分是为了处理事务管理,也许它可能会干扰你的手动事务调用?

虽然您当然可以使用AOP范围的代理进行事务管理,但为什么不在服务层方法上使用@Transactional(readOnly = false | true)注释?在您的服务层方法的Spring配置文件中,您需要做的就是添加

<tx:annotation-driven />

分别参见有关事务管理和ORM数据访问的Spring参考文档的第10章和第13章:

http://static.springsource.org/spring/docs/3.0.x/reference/index.html

最后,如果您正在使用Spring 3,则可以通过将Spring代理的SessionFactory bean注入DAO代码来消除代码中对Spring Framework的引用 - 不再需要使用HibernateDaoSupport。只需注入SessionFactory,获取当前Session,并根据Hibernate示例使用Hibernate。 (如果需要,您可以在同一个应用程序中结合使用HibernateDaoSupport和基于SessionFactory的简单Hibernate代码。)

答案 1 :(得分:2)

如果您看到JavaDoc for HibernateDaoSupport.getSession(),它会说它将获得一个新会话或者为您提供现有事务使用的会话。在您的情况下,已经没有使用HibernateDaoSupport列出的事务。

因此,如果你使用getHibernateTemplate()。getSession()而不是getSession(),你应该得到HibernateTemplate使用的会话,然后上面应该可以工作。

请告诉我它是怎么回事。

编辑:

我同意受保护......我的坏。因此,另一个选择是保持会话线程绑定,这通常是Web应用程序中的最佳实践。如果HibernateDaoSupport将要找到一个线程绑定会话,那么它将不会创建一个新的并使用相同的会话。那应该让你做回滚。