首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法使用Hibernate模板回滚事务

无法使用Hibernate模板回滚事务
EN

Stack Overflow用户
提问于 2013-07-29 12:23:16
回答 2查看 1.5K关注 0票数 0

我使用Spring3.1和Hibernate 3.0以及下面的配置来测试声明性事务,但是看不到回滚语句。

这里我注意到,每次它打开一个新的会话。我猜这可能会导致这个问题。

我的配置/代码中有什么错误吗?

代码语言:javascript
运行
复制
{
    Log
    ----
    09:40:54.909 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
    09:40:54.914 [main] DEBUG o.s.t.i.NameMatchTransactionAttributeSource - Adding transactional method [save*] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-SNTransException]
    09:40:54.914 [main] DEBUG o.s.t.i.NameMatchTransactionAttributeSource - Adding transactional method [get*] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly]
    09:40:54.914 [main] DEBUG o.s.t.i.NameMatchTransactionAttributeSource - Adding transactional method [*] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT]

    09:40:54.936 [main] DEBUG o.s.o.hibernate3.SessionFactoryUtils - Opening Hibernate Session
    09:40:54.960 [main] DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 13750710549
    09:40:54.978 [main] DEBUG o.h.e.def.AbstractSaveEventListener - executing identity-insert immediately
    09:40:54.979 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    09:40:54.979 [main] DEBUG org.hibernate.jdbc.ConnectionManager - opening JDBC connection
    09:40:54.979 [main] DEBUG o.s.j.d.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/test]
    09:40:54.992 [main] DEBUG org.hibernate.SQL - insert into springtrans.users (username, password, status) values (?, ?, ?)
    Hibernate: insert into springtrans.users (username, password, status) values (?, ?, ?)
    09:40:55.009 [main] DEBUG o.h.id.IdentifierGeneratorFactory - Natively generated identity: 458
    09:40:55.009 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    09:40:55.013 [main] DEBUG o.s.orm.hibernate3.HibernateTemplate - Eagerly flushing Hibernate session
    09:40:55.014 [main] DEBUG o.h.e.d.AbstractFlushingEventListener - processing flush-time cascades
    09:40:55.014 [main] DEBUG o.h.e.d.AbstractFlushingEventListener - dirty checking collections
    09:40:55.018 [main] DEBUG org.hibernate.engine.Collections - Collection found: [com.snsystems.data.Users.userSettingses#458], was: [<unreferenced>] (initialized)



    09:40:55.031 [main] DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 13750710550
    09:40:55.032 [main] DEBUG o.h.e.def.AbstractSaveEventListener - executing identity-insert immediately
    09:40:55.032 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    09:40:55.032 [main] DEBUG org.hibernate.jdbc.ConnectionManager - opening JDBC connection
    09:40:55.032 [main] DEBUG o.s.j.d.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/test]
    09:40:55.047 [main] DEBUG org.hibernate.SQL - insert into springtrans.user_settings (user_id, last_login_ip, failed_logins) values (?, ?, ?)
    Hibernate: insert into springtrans.user_settings (user_id, last_login_ip, failed_logins) values (?, ?, ?)
    09:40:55.055 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    09:40:55.061 [main] DEBUG o.h.util.JDBCExceptionReporter - could not insert: [com.snsystems.data.UserSettings] [insert into springtrans.user_settings (user_id, last_login_ip, failed_logins) values (?, ?, ?)]
    com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'last_login_ip' cannot be null

}    

applicationContext.xml
{
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location"><value>/jdbc.properties</value></property>
    </bean>

    <!-- Data Source -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
        <property name="url"><value>${jdbc.url}</value></property>
        <property name="username"><value>${jdbc.username}</value></property>
        <property name="password"><value>${jdbc.password}</value></property>
    </bean>


    <!-- Spring hibernate integration -->   
    <!-- Transaction Manager -->
    <bean id="transactionManager" 
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- Transaction Template Bean -->
    <bean id="transactionTemplate" abstract="true"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager">
            <ref local="transactionManager" />
        </property>
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="view*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="delete*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

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

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />    
        <property name="mappingResources">    
            <list>
                <value>/com/snsystems/data/Users.hbm.xml</value>
                <value>/com/snsystems/data/UserSettings.hbm.xml</value>
            </list>   
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.generate_statistics">true</prop>
            </props>
        </property>   
    </bean>

    <bean id="usersDao" class="com.snsystems.dao.impl.UsersDaoImpl">
        <property name="hibernateTemplate" ref="hibernateTemplate" />
    </bean>

    <bean id="userSettingsDao" class="com.snsystems.dao.impl.UserSettingsDaoImpl">
        <property name="hibernateTemplate" ref="hibernateTemplate" />
    </bean>

    <bean id="userService" class="com.snsystems.service.impl.UsersServiceImpl">
        <property name="usersDao" ref="usersDao" />
        <property name="userSettingsDao" ref="userSettingsDao" />
    </bean>



  <tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
    <tx:method name="save*" rollback-for="SNTransException"/>
    <tx:method name="get*" read-only="true"/>
    <tx:method name="*"/>
  </tx:attributes>
  </tx:advice>

  <aop:config>
  <aop:pointcut id="userServiceOperation" expression="execution(* com.snsystems.service..Service.*(..))"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="userServiceOperation"/>
  </aop:config>

}

代码语言:javascript
运行
复制
UsersDaoImpl


public class UsersDaoImpl implements IUsersDao {

    private HibernateTemplate hibernateTemplate;

    public void saveOrUpdateUsers(Users users) throws PersistenceException {
        try {
            hibernateTemplate.saveOrUpdate(users);
        } catch (Exception e) {
            throw new PersistenceException(e);
        }

    }

    public void deleteUsers(Users users) throws PersistenceException {
        try {
            hibernateTemplate.delete(users);
        } catch (Exception e) {
            throw new PersistenceException(e);
        }
    }

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

}



UsersServiceImpl 

public class UsersServiceImpl implements IUsersService
{
    private IUsersDao usersDao = null;

    private IUserSettingsDao userSettingsDao = null;

    public void saveOrUpdateUsers(Users users) throws SNTransException {
        try {
            usersDao.saveOrUpdateUsers(users);
        } catch (PersistenceException e) {
            throw new SNTransException(e);
        }
    }

    public void deleteUsers(Users users) throws SNTransException {
        try {
            usersDao.deleteUsers(users);
        } catch (PersistenceException e) {
            throw new SNTransException(e);
        }
    }


    public void saveOrUpdateUserSettings(UserSettings userSettings) throws SNTransException {
        try {
            userSettingsDao.saveOrUpdateUserSettings(userSettings);
        } catch (PersistenceException e) {
            throw new RuntimeException(e);
        }
    }

    public void deleteUserSettings(UserSettings userSettings) throws SNTransException {
        try {
            userSettingsDao.deleteUserSettings(userSettings);
        } catch (PersistenceException e) {
            throw new SNTransException(e);
        }
    }


..  setters and getters for dao's
}



UsersServiceTest
{
public class UsersServiceTest {

    private static ClassPathXmlApplicationContext context = null;
    private static IUsersService usersService = null;
    private static Users users = null;
    private static UserSettings userSettings = null; 

    @Before
    public void setUp() {
        try {

            context = new ClassPathXmlApplicationContext("applicationContextBack.xml");
            usersService = (IUsersService) context.getBean("userService");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @After
    public void tearDown() throws Exception {
        usersService = null;
        context = null;
    }

    @Test
    public void testSaveOrUpdateUserSettings() throws Exception {

        users = new Users();
        users.setUsername("JUnitTest");
        users.setPassword("JUnitTest");
        users.setStatus("inactive");

        usersService.saveOrUpdateUsers(users);
        assertNotNull("User Id is null", users.getId());

        userSettings = new UserSettings();
        userSettings.setUsers(users);

        usersService.saveOrUpdateUserSettings(userSettings);
        assertNotNull("UserSettings Id is null", userSettings.getId());
    }

}


}
EN

回答 2

Stack Overflow用户

发布于 2013-07-29 12:29:41

您应该将@Transactional注释添加到服务(impl)方法中。

示例:

代码语言:javascript
运行
复制
@Transactional
public void saveOrUpdateUsers(Users users) {
   ...
}
票数 0
EN

Stack Overflow用户

发布于 2013-07-30 08:52:50

因此,您希望spring transaction manager在每次测试后回滚事务?那么Spring TestContext Framework可能会帮上忙

向您的测试类添加注释:

代码语言:javascript
运行
复制
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("applicationContext.xml")
@Transactional
public class UsersServiceTest {
}

spring事务管理器将在测试前自动启动一个新事务,并在测试结束时回滚该事务

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17916001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档