【问题标题】:Enable JPA 2nd level cache in Spring Data JPA repository在 Spring Data JPA 存储库中启用 JPA 二级缓存
【发布时间】:2019-09-04 12:29:41
【问题描述】:

我尝试为 Spring Data JPA 启用 JPA 二级缓存。我在 persistence.xml 中启用了缓存:

<persistence-unit name="ds-default">
    <jta-data-source>SAMPLE_DATASOURCE</jta-data-source>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
        <property name="hibernate.cache.use_second_level_cache" value="true" />
        <property name="hibernate.cache.use_query_cache" value="true" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.cache.region.factory_class" value="org.jboss.as.jpa.hibernate5.infinispan.InfinispanRegionFactory" />
    </properties>
</persistence-unit>

在我的存储库中,我还提供了缓存的查询提示:

public interface SampleRepository extends JpaRepository<SampleEntity, String> {

    @Override
    @QueryHints(value = {
            @QueryHint(name = "org.hibernate.cacheable", value = "true")
    })
    List<SampleEntity> findAll();
}

我希望 findAll 查询的结果应该被缓存,并且我应该在日志中只看到一个选择查询。但是,我不止一次看到它,这使我得出缓存配置不正确的结论。我错过了什么?

我不想使用 Spring Cache 机制(我不使用 Spring Boot 等)。

【问题讨论】:

  • 如果您在 java 中配置 LocalContainerEntityManagerFactory,请在 java 代码中添加属性,而不是在 persistence.xml 中。
  • 我没有自己创建EntityManagerFactory(我通过@PersistenceContext注入EntityManager)
  • 请阅读我的评论。根据您的问题,您没有使用 Spring Boot,因此您的配置中有一些东西可以配置 LocalContainerEntityManagerFactory,这反过来又会创建 EntityManagerFactory
  • 它由应用服务器(JBoss 或 WebSphere)提供。
  • 您的 Spring 配置中必须有一些东西可以添加 bean,否则它将无法工作。或者您没有使用 Spring,而是在 JEE 环境中使用 Spring Data JPA(这是可能的,但在回答问题时会有很大的不同!)。还要确保您的实体是可缓存的(即具有 @Cacheable 注释,否则它也不会缓存。

标签: hibernate jpa spring-data-jpa


【解决方案1】:

我可以给你一些检查和遵循的步骤以及 github 中的示例项目:

  1. 签入persistence.xml

    <persistence-unit name="testPersistenceUnit" transaction-type="JTA">
    ...
            <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
           <properties>
    ...
            <property name="hibernate.cache.use_second_level_cache" value="true"/>
            <property name="hibernate.cache.use_query_cache" value="true"/>
            <property name="hibernate.cache.region_prefix" value="hibernate.test"/><!-- Optional -->
             <!-- Use Infinispan second level cache provider -->
            <property name="hibernate.cache.region.factory_class" value="org.infinispan.hibernate.cache.v53.InfinispanRegionFactory"/>
    
                <!-- Optional: Initialize a caches (for standalone mode / test purpouse) -->
                <property name="hibernate.cache.infinispan.cfg"
                          value="META-INF/infinispan-configs-local.xml"/> 
    ...
           </properties>
    </persistence>
    

PS:“org.infinispan.hibernate.cache.v53.InfinispanRegionFactory”包取决于你的maven依赖和Hibernate版本。

  1. 如果你想使用 JCache 拦截器。添加到 beans.xml:

    <interceptors>
        <class>org.infinispan.jcache.annotation.InjectedCacheResultInterceptor</class>
        <class>org.infinispan.jcache.annotation.InjectedCachePutInterceptor</class>
        <class>org.infinispan.jcache.annotation.InjectedCacheRemoveEntryInterceptor</class>
        <class>org.infinispan.jcache.annotation.InjectedCacheRemoveAllInterceptor</class>
    </interceptors>
    

PS。请记住,对于缓存管理器未注入托管环境的环境,Infinispan 有一个在拦截器名称中没有“注入”的变体。

  1. 检查您的缓存是否已配置(在您的应用服务器中)或您的 cdi 生产者。例如。

    @ApplicationScoped
    public class CacheConfigProducer {
    @Produces
    public Configuration defaultCacheConfiguration() {
    return new ConfigurationBuilder().simpleCache(false).customInterceptors().addInterceptor()
        .interceptor(new TestInfinispanCacheInterceptor()).position(Position.FIRST).expiration().lifespan(60000l)
        .build();
    }
    }
    
  2. 将您的提示添加到您的存储库中:

    @Eager public interface CacheableReadWriteRepository extends ReadWriteRepository<CacheableEntity, Integer>{
    
        @QueryHints(value = { @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_CACHEABLE, value = "true")})
        List<CacheableEntity> findByValue(Integer value);
    }
    
  3. 注意将@Cacheable 添加到您的实体中

你有这个项目与 Spring Data JPA 和 CDI 集成 (spring-data-jpa with cdi)。它对 JCache、Hibernate 二级缓存和查询缓存进行了测试。

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    • 2016-06-18
    • 1970-01-01
    • 2015-12-29
    • 2018-08-06
    • 2016-12-26
    相关资源
    最近更新 更多