无法检索PlatformTransactionManager以进行测试上下文的@Transactional测试

当尝试在事务之间测试Hibernate(版本4)EHCache的缓存function时 – 它失败: Failed to retrieve PlatformTransactionManager for @Transactional test for test context

测试

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { ApplicationConfig.class, CachingConfig.class }, loader = AnnotationConfigContextLoader.class) @PersistenceContext @Transactional public class EHCacheTest extends AbstractTransactionalJUnit4SpringContextTests { @Autowired private SessionFactory sessionFactory; @Test public void testTransactionCaching(){ Session session = sessionFactory.getCurrentSession(); System.out.println(session.get(CustomerEntity.class, 1)); Query query = session.createQuery("from CustomerEntity where CustomerEntity.customerId<10").setCacheable(true).setCacheRegion("customer"); @SuppressWarnings("unchecked") List customerEntities = query.list(); System.out.println(customerEntities); TestTransaction.flagForCommit(); TestTransaction.end(); TestTransaction.start(); Session sessionNew = sessionFactory.getCurrentSession(); System.out.println(sessionNew.get(CustomerEntity.class, 1)); Query anotherQuery = sessionNew.createQuery("from CustomerEntity where CustomerEntity.customerId<10"); anotherQuery.setCacheable(true).setCacheRegion("customer"); @SuppressWarnings("unchecked") List customerListfromCache = anotherQuery.list(); System.out.println(customerListfromCache); TestTransaction.flagForCommit(); TestTransaction.end(); } } 

手动编程事务处理是按照Spring 4.x在文档中建议的方式实现的。

ApplicationConfig

 @Configuration @EnableTransactionManagement @EnableJpaRepositories (basePackages = { "com.hibernate.query.performance.persistence" }, transactionManagerRef = "jpaTransactionManager") @EnableJpaAuditing @PropertySource({ "classpath:persistence-postgresql.properties" }) @ComponentScan({ "com.hibernate.query.performance.persistence" }) public class ApplicationConfig { @Autowired private Environment env; public ApplicationConfig() { super(); } @Bean public LocalSessionFactoryBean sessionFactory() { final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(applicationDataSource()); sessionFactory.setPackagesToScan(new String[] { "com.hibernate.query.performance.persistence.model" }); sessionFactory.setHibernateProperties(hibernateProperties()); return sessionFactory; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); emf.setDataSource(applicationDataSource()); emf.setPackagesToScan(new String[] { "com.hibernate.query.performance.persistence.model" }); final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); emf.setJpaVendorAdapter(vendorAdapter); emf.setJpaProperties(hibernateProperties()); return emf; } @Bean public DataSource applicationDataSource() { final BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); return dataSource; } @Bean public PlatformTransactionManager hibernateTransactionManager() { // TODO: Really need this? final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(sessionFactory().getObject()); return transactionManager; } @Bean public PlatformTransactionManager jpaTransactionManager() { // TODO: Really need this? final JpaTransactionManager transactionManager = new JpaTransactionManager(); // http://stackoverflow.com/questions/26562787/hibernateexception-couldnt-obtain-transaction-synchronized-session-for-current transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); return transactionManager; } @Bean public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { return new PersistenceExceptionTranslationPostProcessor(); } private final Properties hibernateProperties() { final Properties hibernateProperties = new Properties(); hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); hibernateProperties.setProperty("hibernate.show_sql", "true"); hibernateProperties.setProperty("hibernate.format_sql", "true"); // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); hibernateProperties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); // Envers properties hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix")); // TODO: Really need this? return hibernateProperties; } } 

CachingConfig

 @Configuration @EnableCaching public class CachingConfig implements CachingConfigurer { @Bean(destroyMethod="shutdown") public net.sf.ehcache.CacheManager ehCacheManager() { CacheConfiguration cacheConfiguration = new CacheConfiguration(); cacheConfiguration.setName("myCacheName"); cacheConfiguration.setMemoryStoreEvictionPolicy("LRU"); cacheConfiguration.setMaxElementsInMemory(1000); net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration(); config.addCache(cacheConfiguration); return net.sf.ehcache.CacheManager.create(config); } @Bean @Override public CacheManager cacheManager() { return new EhCacheCacheManager(ehCacheManager()); } @Override public CacheResolver cacheResolver() { return null; } @Bean @Override public KeyGenerator keyGenerator() { return new SimpleKeyGenerator(); } @Override public CacheErrorHandler errorHandler() { return null; } } 

错误

 java.lang.IllegalStateException: Failed to retrieve PlatformTransactionManager for @Transactional test for test context [DefaultTestContext@d8355a8 testClass = EHCacheTest, testInstance = com.hibernate.query.performance.EHCacheTest@3532ec19, testMethod = testTransactionCaching@EHCacheTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@59fa1d9b testClass = EHCacheTest, locations = '{}', classes = '{class com.hibernate.query.performance.config.ApplicationConfig, class com.hibernate.query.performance.config.CachingConfig}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.AnnotationConfigContextLoader', parent = [null]]]. 

如何使其工作?


更新:

通过添加使其工作,但@TestExecutionListeners是否真的需要@TestExecutionListeners

 @Transactional(transactionManager = "hibernateTransactionManager") @TestExecutionListeners({}) 

如果未明确指定@Transactional,则需要在应用程序上下文中使用名为transactionManager的bean。 使用@Transaction批注值属性指定要与测试一起使用的事务管理器

例如,如果要使用hibernateTransactionManager,请将其指定为

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { ApplicationConfig.class, CachingConfig.class }, loader = AnnotationConfigContextLoader.class) @PersistenceContext @Transactional("hibernateTransactionManager") public class EHCacheTest extends AbstractTransactionalJUnit4SpringContextTests { } 

否则,将要使用的事务管理器重命名为具有默认名称transactionManager

 @Bean public PlatformTransactionManager transactionManager() { // TODO: Really need this? final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(sessionFactory().getObject()); return transactionManager; }