2

我遇到了类似于此问题中描述的问题

我有一个在开发环境中运行良好的测试套件。在 Bitbucket Pipelines 中执行时,其中一项测试失败,但有以下异常:

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)
   ....

我想尝试接受的解决方案,但我不知道如何将它应用到我的项目中。第二种解决方案取决于 ehcache.xml 文件。我没有这个文件,一切都在 JavaConfig 中配置。如何在 JavaConfig 中采用EhCache + JCache (JSR-107) 的建议解决方案?

我的缓存配置:

@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”。关于我的配置,我该如何做到这一点?

4

3 回答 3

1

一种选择是提供CachingProvider不共享CacheManager-s 的自定义。可以在此处找到示例解决方案。

于 2020-02-03T20:04:55.800 回答
0

您正在谈论的建议解决方案基于 Ehcache 2。您正在使用 Ehcache 3(对您有好处),因此它无效。

Spring会正常关闭CacheManager,你不需要照顾任何东西。此外,您不需要通过CachingProvider. 你可以@Autowired这样javax.cache.CacheManager,你一定会得到正确的。

但是,您使用的是 Hibernate。您应该确保 Spring 和 Hibernate 使用相同的CacheManager. 配置它的方式取决于 Spring 和 Hibernate 版本。

我们可以有完整的堆栈跟踪吗?现在感觉好像有什么东西正在关闭CacheManager而不从CachingProvider. 这是不可能的,除非您在org.ehcache.CacheManager不关闭javax.cache.CacheManager包装的情况下关闭它。关闭后者将导致注销。

于 2018-11-25T03:07:46.750 回答
0

用 .注释你失败的测试类@AutoConfigureCache。默认情况下,此注解将安装一个NoOpCacheManager,即一个基本的、CacheManager适合禁用缓存的无操作实现,通常用于在没有实际后备存储的情况下支持缓存声明。它只会将任何项目接受到缓存中,而不是实际存储它们。

@AutoConfigureCache 上的 Spring 文档

@NoOpCacheManager 上的 Spring 文档

于 2021-01-15T07:54:42.870 回答