Spring @transactional,单元测试失败

时间:2016-02-10 08:10:59

标签: spring hibernate junit

我是hibernate + spring setup的新手。

我严格使用注释并尝试编写一个简单的测试。

这是配置

@Configuration
@EnableTransactionManagement
public class DatabaseConfiguration {

    @Bean
    DataSource dataSource() {
        BasicDataSource ret = new BasicDataSource();
        ret.setDriverClassName("com.mysql.jdbc.Driver");
        ret.setUrl("jdbc:mysql://localhost:3306/mydb");
        ret.setUsername("root");
        ret.setPassword("root");
        return ret;
    }

    @Bean
    SessionFactory sessionFactoryBean(DataSource dataSource) {
        LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(
                dataSource);
        sessionBuilder.scanPackages("com.mypackages.domain");
        sessionBuilder.addProperties(getHibernateProperties());
        return sessionBuilder.buildSessionFactory();
    }

    private Properties getHibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.show_sql", "true");
        properties.put("hibernate.hbm2ddl.auto", "create");
        properties.put("hibernate.dialect",
                "org.hibernate.dialect.MySQLDialect");
        return properties;
    }

    @Bean
    HibernateTransactionManager transactionManager(SessionFactory lsfb) {
        HibernateTransactionManager mgr = new HibernateTransactionManager();
        mgr.setSessionFactory(lsfb);
        return mgr;
    }
}

我的Junit测试用例使用@transactional注释。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={DatabaseConfiguration.class})

public class TestMyDao extends AbstractTransactionalJUnit4SpringContextTests  {

    @Autowired
    MyDao dao; 

   @Autowired
   SessionFactory sessionFactory;

    @Test
    @Transactional
    public void testCreate() {
        DomainObj obj = new DomainObj();
        Session session = sessionFactory.getCurrentSession();
        session.save(obj);
    }
}

这段代码失败,因为当前线程没有附加会话。

不是@Transactional假设要照顾它吗?如果不是如何使用@Transactional并获得对会话的访问权限?

错误

Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@6bf256fa] to process 'after' execution for test: method [public void com.mytest.testCreate()], instance [com.mydao.TestDao@2227a6c1], exception 
[java.lang.IllegalStateException: Already value [org.springframework.orm.hibernate5.SessionHolder@15fa55a6] for key [org.hibernate.internal.SessionFactoryImpl@4a7761b1] bound to thread [main]] 
java.lang.IllegalStateException: No value for key [org.hibernate.internal.SessionFactoryImpl@4a7761b1] bound to thread [main]
at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:210)
    at org.springframework.orm.hibernate5.HibernateTransactionManager.doCleanupAfterCompletion(HibernateTransactionManager.java:635)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:1016)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:883)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:830)
    at org.springframework.test.context.transaction.TransactionContext.endTransaction(TransactionContext.java:125)
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:218)
    at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:313)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:94)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

0 个答案:

没有答案