代码之家  ›  专栏  ›  技术社区  ›  naXa stands with Ukraine

缓存已关闭,导致运行测试套件时出现异常

  •  0
  • naXa stands with Ukraine  · 技术社区  · 7 年前

    我遇到了与中描述的类似的问题 this question .

    我有一个在开发环境中运行良好的测试套件。当在Bitbucket管道中执行时,其中一个测试失败,但以下情况除外:

    org.springframework.dao.InvalidDataAccessApiUsageException: Cache[model.Role] is closed; nested exception is java.lang.IllegalStateException: Cache[model.Role] is closed
        at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:364)
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527)
        at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
        at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
       ....
    

    我想试试 accepted solution 但我不知道如何将其应用到我的项目中。这个 second solution 取决于ehcache。xml文件。我没有这个文件,一切都是在JavaConfig中配置的。我如何采用建议的解决方案 EhCache+JCache

    我的缓存配置:

    @Configuration
    @EnableCaching
    public class CacheConfig {
    
        private final javax.cache.configuration.Configuration<Object, Object> jcacheConfiguration =
                Eh107Configuration.fromEhcacheCacheConfiguration(CacheConfigurationBuilder
                        .newCacheConfigurationBuilder(Object.class, Object.class,
                                ResourcePoolsBuilder.newResourcePoolsBuilder()
                                        .heap(100, EntryUnit.ENTRIES))
                        .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(60)))
                        .build());
    
        @Bean
        public JCacheManagerCustomizer cacheManagerCustomizer() {
            return cm -> {
                createIfNotExists(cm, "model.Role");
                createIfNotExists(cm, "model.User.roles");
                // ...
            };
        }
    
        private void createIfNotExists(CacheManager cacheManager, String cacheName) {
            if (cacheManager.getCache(cacheName) == null) {
                cacheManager.createCache(cacheName, jcacheConfiguration);
            }
        }
    }
    

    渐变依赖项:

    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-cache'
    implementation group: 'javax.cache', name: 'cache-api'
    implementation group: 'org.ehcache', name: 'ehcache'
    implementation group: 'org.hibernate', name: 'hibernate-jcache'
    

    @SpringBootTest
    @RunWith(SpringJUnit4ClassRunner.class)
    public class SecondLevelCacheTest {
        @Autowired
        private RoleRepository roleRepository;
        private CacheManager manager;
    
        @Before
        public void initCacheManager() {
            CachingProvider provider = Caching.getCachingProvider();
            manager = provider.getCacheManager();
    
            final String cacheRegion = "model.Role";
            manager.getCache(cacheRegion).clear();
        }
    
        @Test
        public final void givenEntityIsLoaded_thenItIsCached() {
            final String cacheRegion = "model.Role";
    
            boolean hasNext = manager.getCache(cacheRegion).iterator().hasNext();
            final Role role = roleRepository.findByName("USER");
            boolean hasNext2 = manager.getCache(cacheRegion).iterator().hasNext();
            final Role role2 = roleRepository.findByName("USER");
    
            Assert.assertFalse(hasNext);
            Assert.assertTrue(hasNext2);
        }
    }
    

    投票最多的解决方案是“在测试上下文中将共享属性设置为false”关于我的配置,我如何做到这一点?

    1 回复  |  直到 7 年前
        1
  •  1
  •   alexmagnus    6 年前

    CachingProvider 这不共享 CacheManager here .

        2
  •  0
  •   Henri    7 年前

    弹簧将负责关闭 CacheManager 所以通常情况下,你不需要处理任何事情。此外,您不需要通过 CachingProvider . 你可以 @Autowired 这个 javax.cache.CacheManager 这样你一定会得到正确的答案。

    但是,您正在使用Hibernate。您应该确保Spring和Hibernate使用相同的 缓存管理器 . 配置它的方式取决于Spring和Hibernate版本。

    缓存管理器 不需要从 org.ehcache.CacheManager 不关闭 javax。隐藏物缓存管理器 包装它。关闭后者将导致注销。

        3
  •  0
  •   Dana Georgescu    5 年前

    用注释您的失败测试类 @AutoConfigureCache . 默认情况下,此注释将安装 NoOpCacheManager ,即基本,无操作 CacheManager

    Spring Documentation on @AutoConfigureCache

    Spring Documentation on @NoOpCacheManager

    推荐文章