使用带有Spring的@Transactional Annotation的HIbernate数据不会持续存在

时间:2010-02-02 18:47:20

标签: java hibernate spring transactions

我有一个我正在编写的应用程序,它将使用Spring和Hibernate。在我的服务层中,我注入了一个DAO,它将执行一些非常基本的CRUD操作。对于grins,我创建了一个注释如下的方法:

@Transactional(readOnly = false, propogation=Propogation.REQUIRES_NEW)
public void doSomeWork(Dao dao, Entity e){
    //do some searching
    dao.persist(e);
    dao.findAll(Entity.clz);
}

dao persist方法如下所示:

public void persist(Entity e){
     session.saveOrUpdate(e); //This has already been built using a SessionFactory
}

dao findAll方法看起来像这样

public void findAll(Class clz) {
     session.createCriteria(clz).list();
}

现在,一切似乎都在运行,好的。插入(持久化)我的对象后,我可以使用findAll方法(以及由Data Store分配的新主键ID)来查看它,但是,当“doSomeWork”方法完成时,我的数据实际上并不存在获取持久化到基础数据存储区(Oracle 10g)。

但是,如果我删除@Transactional注释并使用Hibernate的session.getTransaction()。begin()和session.getTransaction()。commit()(或rollback),代码就像我预期的那样工作。

因此,我的基本问题是:Hibernate是否实际上没有将Spring的事务管理用于实际的事务管理?

在我的bean-config文件中,我声明了一个TransactionManager bean,一个SessionFactory bean,我也包含在配置文件中。

除了更好的Spring和Hibernate工作知识外,我还有什么可能遗漏的?

4 个答案:

答案 0 :(得分:4)

不要忘记为<tx:annotation-driven>支持

添加@Transactional

答案 1 :(得分:2)

听起来像spring并没有真正注入事务处理代码。 你在配置文件中有这样的东西,告诉spring在哪里寻找带注释的类吗?

<beans xmlns:context="http://www.springframework.org/schema/context" ...
    xsi:schemaLocation="http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd ..." >

    ...
    <context:annotation-config/>
    <context:component-scan base-package="mypackage.dao.impl"/>

    <bean name="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

</beans>

答案 2 :(得分:1)

您使用什么方法从会话工厂获取会话对象?您使用的是openSession(),还是getCurrentSession(),还是其他什么?这很重要,因为你需要将会话绑定到spring事务(我怀疑openSession是否适合你的场景)

我建议您使用Spring的hibernateTemplate来调用saveOrUpdate并保持,而不是使用会话对象。通过这种方式,您可以确保它将绑定到事务,并且,如果您更改事务管理策略,则无需更改代码。

答案 3 :(得分:1)

好的,好的,感谢所有回复的人...它帮助我弄清楚我做错了什么......

在我过于热心的“概念验证”中,直到我意识到我的“简单的java类,主要方法将完成我的所有工作”并不是由春天管理,我才真正意识到发生了什么事。因此没有真正的交易管理。这绝不会像产品应用程序那样,由具有控制器bean,服务等的app-server管理。

然后我突然意识到......“服务”......我将有一个服务层,这就是交易支持所在的地方。所以,就像下雨一样,我创建了一个简单的服务bean(用@Transactional标记),它就像我希望的那样工作。所以,我在我的服务上调用方法,它调用我的Dao和bam上的方法!有用。

再次感谢所有帮助我得出这个结论的人。