我是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)