Spring@transactional,单元测试失败

Spring@transactional,单元测试失败,spring,hibernate,junit,Spring,Hibernate,Junit,我是hibernate+spring设置的新手 我严格使用注释,并试图编写一个简单的测试 这里是配置 @Configuration @EnableTransactionManagement public class DatabaseConfiguration { @Bean DataSource dataSource() { BasicDataSource ret = new BasicDataSource(); ret.setDriverCla

我是hibernate+spring设置的新手

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

这里是配置

@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
并访问会话

错误


仅添加
@Transactional
是不够的,您还需要指示测试需要在事务下运行。通过扩展
AbstractTransactionalJUnitSpringContextTests
或将
TransactionalTestExecutionListener
作为侦听器包含在
ContextConfiguration
@M.Deinum中,我现在正在从“AbstractTransactionalJUnitSpringContextTests”扩展测试类,但仍然面临相同的错误。我现在已经把这个错误写在帖子里了。请告知。谢谢添加您的测试用例,而不仅仅是方法。不是因为您的测试失败了方法之后的
@After,所以不确定您在该方法中做了什么。…@M.Deinum添加了周围的代码。我没有编写任何@After方法。仅添加
@Transactional
是不够的,您还需要指示测试需要在事务下运行。通过扩展
AbstractTransactionalJUnitSpringContextTests
或将
TransactionalTestExecutionListener
作为侦听器包含在
ContextConfiguration
@M.Deinum中,我现在正在从“AbstractTransactionalJUnitSpringContextTests”扩展测试类,但仍然面临相同的错误。我现在已经把这个错误写在帖子里了。请告知。谢谢添加您的测试用例,而不仅仅是方法。不是因为您的测试失败了
方法之后的
@After,所以不确定您在该方法中做了什么。…@M.Deinum添加了周围的代码。我没有写任何@After方法。
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)