2016-05-20 2 views
4

トランザクション間のHibernate(バージョン4)EHCacheのキャッシュ機能をテストしようとすると、失敗します:Failed to retrieve PlatformTransactionManager for @Transactional test for test contextテストコンテキストの@TransactionalテストでPlatformTransactionManagerを取得できませんでした

テスト

@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<CustomerEntity> 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<CustomerEntity> customerListfromCache = anotherQuery.list(); 
     System.out.println(customerListfromCache); 

     TestTransaction.flagForCommit(); 
     TestTransaction.end(); 
    } 
} 

手動プログラムによるトランザクション処理は春4.xのはdocumentationに示唆するような方法を実施しました。作る方法

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 [[email protected] testClass = EHCacheTest, testInstance = [email protected], testMethod = [email protected], testException = [null], mergedContextConfiguration = [[email protected] 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が本当に必要とされる場合にかかわらず、わからなく、追加することで働かせた:

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

答えて

4

@Transactionalがあれば、アプリケーションのコンテキストで名前のTransactionManagerを持つBeanが必要です明示的に指定されていない。あなたがそうでなければあなたが使用するトランザクションマネージャの名前を変更hibernateTransactionManagerが

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

としてこれを指定使用したい場合たとえば@Transaction注釈value属性

を使用して、テストで使用するトランザクションマネージャを指定しますデフォルトの名前を持つtransactionManager

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