我正在尝试在使用 spring-boot-starter-data-jpa 的 Spring-Boot 应用程序上激活 Hibernate 2nd Level Cache。我使用 Ehcache 2 并在我的类路径中有 hibernate-ehcache
我使用了以下属性
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
spring.jpa.properties.hibernate.generate_statistics=true
我也像这样在 src/main/resources 中创建了 ehcache.xml(只是一个使用永不过期的缓存的测试)
<ehcache updateCheck="false" monitoring="autodetect"
dynamicConfig="true">
<defaultCache
maxElementsInMemory="100000"
maxElementsOnDisk="10000000"
eternal="true"
overflowToDisk="false">
</defaultCache>
</ehcache>
实体也用
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
注释在日志文件中我可以清楚地看到默认缓存用于实体,因此它似乎可以识别注释并像往常一样初始化缓存。WARN .h.c.e.AbstractEhcacheRegionFactory : HHH020003: Could not find a specific ehcache configuration for cache named [at.test.demo.persistence.entity.Employee]; using defaults.
现在为了测试这一点,我编写了一个简单的测试,插入 3 个员工并使用通常的 JPA-Entitymanager 加载它们。之后,我试图通过调用以下代码来验证加载的 Employee 是否真的进入了缓存:
Assert.assertTrue(em.getEntityManagerFactory().getCache().contains(Employee.class, employeeId));
但这总是失败。此外,SessionFactory-Statics 对所有内容都显示为零,这是不对的。
有任何想法吗?
编辑
我剥离了该项目并将其添加到公共(public) gitlab 存储库中,以便您重现它:https://gitlab.com/matrium00/reproduce-cache-issue
由于这个问题,现在有一个单元测试失败了。
编辑2
以下是 em-factory 的工作 XML 配置示例没有 Spring Boot 。我知道我可以在我的配置类中手动创建必要的 bean,但必须有更好的方法:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
autowire="byName" depends-on="flyway">
<property name="packagesToScan" value="at.my.package.demo.persistence.entity"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.default_schema">${jdbc.schema}</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
</props>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
</bean>
最佳答案
您有 @Transactional
测试方法和 @DataJpaTest
上的注释(也意味着 @Transactional
)在你的测试课上。
因为只有一个事务,所以会有一个 session 。当您在同一个事务中访问同一个持久对象时,Hibernate 使用一级缓存( session 缓存)。要在二级缓存中取得成功,您应该有不同的 session (不同的事务)。
简单替换 @DataJpaTest
与 @SpringBootTest
并删除 @Transactional
from test 方法使测试工作。
也可以看看:
关于Spring-Boot - 激活休眠二级缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46650475/