0

我在我的应用程序中使用 spring + hibernate + jersey。我想使用事务,所以我在我的服务层中使用了 spring 的 @Transactional 注释。这是我的 hibernate.cfg.xml:

<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/db</property>
    <property name="hibernate.connection.username">user</property>
  </session-factory>
</hibernate-configuration>

我在这里没有使用 session_context ,所以 spring 可以管理它。在我的 applicationCONtext.xml 中,我定义了 transactionManager:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db"/>
    <property name="user" value="username"/>
</bean>

<context:annotation-config/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
    <property name="packagesToScan">
        <list>
            <value>com.hibernate.pojos</value>
        </list>
    </property>
</bean>

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

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

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

所有匹配 /api/v1/* 的 url 都映射到名为 jersey 的 servlet 和使用的 servlet 类com.sun.jersey.spi.spring.container.servlet.SpringServlet,我已将 com.services 作为要扫描的包传递给该类。在这个包中,我有一个类:

@Path("/app")
@Component
public class testApi() {
    @Autowired
    private DAOImpl daoimpl;

    @POST
    @Path("/create")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Transactional(rollbackFor = {Exception.class})
    public Map<String,Object> testHello(user u) {
        Map response = daoimpl.save(u);
        return response;
    }
}

该类daoimpl具有自动装配的 sessionFactory 并使用sessionFactory.getCurrentSession()方法来获取会话。该方法daoimpl.save(obj)只是将其保存在数据库中。由于我已将 testHello 标记为事务性,我希望一个由 spring 管理的事务开始,然后控制权应该转到实际保存发生的 daoimpl。但是如果没有活动的交易,我得到的保存是无效的。我看过很多帖子,其中在休眠配置中提到了 session_context,因此,spring 无法处理事务。但就我而言,我确保我不提供任何 session_context。我错过了什么?我什至尝试将@transactional 添加到 DAO,因为在我的示例应用程序中,我只是为服务发出一个数据库调用。但这也不起作用。

4

1 回答 1

-1

很可能是您通过 hibernate.cfg.xml 指定会话工厂,然后在 Spring 中再次指定会话工厂,然后将其传递给事务管理器。

不确定说实话,但是我从来没有使用过 hibenate.cfg.xml 然后对我有用(按照您的指定添加了事务配置)。这也为您提供了将连接参数指定为属性并允许您通过 Spring Profiles 或其他一些机制轻松交换数据库配置的优势。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
                                                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

        <bean id="sessionFactory"
                class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
                <property name="dataSource" ref="dataSource" />
                <property name="packagesToScan">
                        <list>
                                <value>uk.co.xyz.domain</value>
                        </list> 
                </property>
                <property name="hibernateProperties">
                        <props>
                                <prop key="hibernate.show_sql">${hibernate.showsql}</prop>
                                <prop key="hibernate.format_sql">true</prop>
                                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                                <prop key="hibernate.hbm2ddl.auto">${hibernate.ddlauto}</prop> 
                                <prop key="hibernate.cache.use_second_level_cache">${hibernate.enablecache}</prop>
                                <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
                        </props>
                </property>
        </bean>

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

</beans>

另请参阅此处,这实际上表明无关紧要:

带有数据源的 applicationContext.xml 或 hibernate.cfg.xml。区别?

于 2013-10-23T22:18:56.353 回答