如何将spring与hibernate会话和事务管理集成?

时间:2022-10-01 21:01:56

I am a beginner in both hibernate and spring. I have understood about the hibernate transaction demarcation (at least I think so). But after coding a few method like this:

我是hibernate和spring的初学者。我已经了解了hibernate事务划分(至少我是这么认为的)。但在编写了一些像这样的方法之后:

sessionFactory.getCurrentSession().beginTransaction();
//do something here
sessionFactory.getCurrentSession().endTransaction();

I started to want to avoid it and want to have it automatically done outside my method such that I only write the "//do something here" part. I have read about the TransactionProxyFactoryBean and think that the xml configuration is very long and have to be repeated for EVERY classes I want to make transactional so if possible I want to avoid using it.

我开始想要避免它,并希望在我的方法之外自动完成它,这样我只能编写“//在这里做某事”部分。我已经阅读了有关TransactionProxyFactoryBean的内容,并认为xml配置非常长,并且必须重复我想要进行事务处理的每个类,所以如果可能的话我想避免使用它。

I tried to use the @Transactional but it doesn't work at all. I have these lines in my applicationContext.xml

我尝试使用@Transactional但它根本不起作用。我在applicationContext.xml中有这些行

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>

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

<tx:annotation-driven transaction-manager="transactionManager" />

and I have already marked my service classes with @Transactional but I always get the "xxx is not valid without active transaction". Here is an example code that give me an error (run in unit test btw):

我已经使用@Transactional标记了我的服务类但是我总是得到“xxx在没有活动事务时无效”。这是一个给我一个错误的示例代码(在单元测试btw中运行):

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{
    "classpath:applicationContext.xml"
})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class UserServiceTest
{
    @Resource
    private UserService userService;

    @Test
    public void testAddUser()
    {
        User us = new User();
        us.setName("any name");
        userService.addUser(us);
    }
}

In this case, the exact error message is: "org.hibernate.HibernateException: save is not valid without active transaction".

在这种情况下,确切的错误消息是:“org.hibernate.HibernateException:如果没有活动事务,save无效”。

UPDATE: I tried calling the userService.addUser() method from outside unit tests (i.e. from actual web application) and I got the same error as well.

更新:我尝试从外部单元测试(即从实际的Web应用程序)调用userService.addUser()方法,我也得到了相同的错误。

This is my hibernate.cfg.xml:

这是我的hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>

        <!-- all my mapping resources here -->
    </session-factory>
</hibernate-configuration>

The userService class is marked with @Transactional. I am using hibernate 3.3.2 and spring 2.5.6.

userService类标有@Transactional。我正在使用hibernate 3.3.2和spring 2.5.6。

Can I have some advice on how to fix this?

我可以就如何解决这个问题提出一些建议吗?

2 个解决方案

#1


15  

Remove the following line, it interferes with Spring-managed transactions:

删除以下行,它会干扰Spring管理的事务:

<property name="current_session_context_class">thread</property> 

#2


1  

@hephestos: The value for the parameter current_session_context_class decides the context to which the session (Hibernate session) must be bound with.

@hephestos:参数current_session_context_class的值决定了会话(Hibernate会话)必须绑定到的上下文。

By default it is bound with the currently running thread. But when "jta" is used to manage transactions, changing the value of this parameter to "jta" binds the session to the current JTA transaction context.

默认情况下,它与当前运行的线程绑定。但是当“jta”用于管理事务时,将此参数的值更改为“jta”会将会话绑定到当前的JTA事务上下文。

Basically it defines the context for the sessions. More information: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/architecture.html#architecture-current-session

基本上它定义了会话的上下文。更多信息:http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/architecture.html#architecture-current-session

#1


15  

Remove the following line, it interferes with Spring-managed transactions:

删除以下行,它会干扰Spring管理的事务:

<property name="current_session_context_class">thread</property> 

#2


1  

@hephestos: The value for the parameter current_session_context_class decides the context to which the session (Hibernate session) must be bound with.

@hephestos:参数current_session_context_class的值决定了会话(Hibernate会话)必须绑定到的上下文。

By default it is bound with the currently running thread. But when "jta" is used to manage transactions, changing the value of this parameter to "jta" binds the session to the current JTA transaction context.

默认情况下,它与当前运行的线程绑定。但是当“jta”用于管理事务时,将此参数的值更改为“jta”会将会话绑定到当前的JTA事务上下文。

Basically it defines the context for the sessions. More information: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/architecture.html#architecture-current-session

基本上它定义了会话的上下文。更多信息:http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/architecture.html#architecture-current-session