弹簧靴&x2B;JPA2和x2B;Hibernate-启用二级缓存

弹簧靴&x2B;JPA2和x2B;Hibernate-启用二级缓存,hibernate,spring-boot,jpa-2.0,second-level-cache,Hibernate,Spring Boot,Jpa 2.0,Second Level Cache,我使用SpringBoot1.2.5和JPA2来注释实体(并将hibernate作为JPA实现的底层) 我想在该设置中使用二级缓存,因此实体被注释为@javax.persistence.Cacheable 我还在application.properties中添加了以下内容: spring.jpa.properties.hibernate.cache.use_second_level_cache=true spring.jpa.properties.hibernate.cache.use_quer

我使用SpringBoot1.2.5和JPA2来注释实体(并将hibernate作为JPA实现的底层)

我想在该设置中使用二级缓存,因此实体被注释为
@javax.persistence.Cacheable

我还在application.properties中添加了以下内容:

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.EhCacheRegionFactory
在启动过程中,hibernate抱怨缺少
EhCacheRegionFactory
,因此我也将此添加到pom中:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
</dependency>

org.hibernate
休眠ehcache
但是像
entityManager.find(Clazz.class,pk)
这样的查询仍在触发DB查询,而不是使用缓存数据


知道缺少什么吗?

类路径中应该有一个ehcache.xml文件。文件应至少包含默认缓存策略。为便于调试,请确保实体未从缓存中逐出:

ehcache.xml:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:noNamespaceSchemaLocation="ehcache.xsd"
  Name="CacheManager" 
  maxBytesLocalHeap="250m">

<defaultCache eternal="true"
...
/>

<cache name="org.hibernate.cache.internal.StandardQueryCache"
       eternal="true"
...
/>
这意味着您的实体缓存注释已正确读取,将使用默认缓存

如果您使用
entityManager.find(Clazz.class,pk)
进行测试,那么这不是查询缓存,而是实体缓存。查询缓存用于查询(em.createQuery(…)和关系


另外,我使用org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory,但我不知道哪个更好。

经过进一步的挖掘,这里是我在
应用程序中缺少的内容。属性

spring.jpa.properties.javax.persistence.sharedCache.mode=ALL
希望它能帮助某人:)

我不确定是否

spring.jpa.properties.javax.persistence.sharedCache.mode=ALL
这是最好的决定

引自

默认情况下,实体不是二级缓存的一部分,建议您坚持此设置。但是,您可以通过在persistence.xml文件中设置共享缓存模式元素或在配置中使用javax.persistence.sharedCache.mode属性来覆盖这一点

鉴于

ENABLE_SELECTIVE(默认值和建议值):除非显式标记为可缓存,否则不会缓存实体

那么,您是否还没有用@javax.persistence.Cacheable或者更确切地说@org.hibernate.annotations.Cache注释所有受影响的实体?这可能会导致查询缓存试图在二级缓存中查找受影响的实体但未成功,然后通过一次选择开始获取每个实体。

您添加了吗

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY) 

在要缓存的类上?

您可以使用第三方缓存提供程序,包括JCache、Ehcache、Gvava缓存、Hazelcast缓存、咖啡因缓存

请参阅上的此答案,了解如何在Spring boot中启用和配置二级缓存。

总结所有内容(二级缓存和查询缓存):

首先要做的是向类路径添加缓存提供程序(我建议使用EhCache)

休眠<5.3

添加
hibernate ehcache
依赖项。此库包含现已停止使用的EhCache 2

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>your_hibernate_version</version>
</dependency>
对于EhCache 3(或Hibernate>=5.3),应使用此区域工厂:

factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
您还可以为Hibernate启用跟踪级别日志记录,以验证代码和配置:

logging:
  level:
    org:
      hibernate:
        type: trace
现在让我们继续讨论代码。要在实体上启用二级缓存,需要添加以下两个注释:

@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) //Provide cache strategy.
public class MyEntity {
  ...
}
注意-如果要缓存您的
@OneToMany
@ManyToOne
关系,请在此字段上添加
@cache
注释

要在spring数据jpa存储库中启用查询缓存,您需要添加适当的
QueryHint

public class MyEntityRepository implements JpaRepository<MyEntity, Long> {

  @QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
  List<MyEntity> findBySomething(String something);

}

希望您在您的配置类中使用
@EnableCaching
或在xml文件中使用
启用了缓存管理。尽管它仅用于Spring缓存,但我希望使用JPA2缓存(更新问题以指示我正在使用
@javax.persistence.Cacheable
)在类级别Hello上,我遵循了您和其他人提到的所有步骤,但仍然无法在hibernate中启用二级缓存。我使用的是spring boot和hibernate 5.4.15 final jar,而在spring boot中,它为我提供了ehcache 2.10.6 jar。我收到以下警告:“HH020100:Hibernate的Ehcache二级缓存提供程序已弃用。”不,情况并非如此。必须明确设置spring.jpa.properties.javax.persistence.sharedCache.mode。无论是全部设置还是不同设置,这都是另一回事,与此问题无关。再加上我的两分钱:使用Spring Boot 1.4、Ehcache和Hibernate 5.1,您确实需要至少设置区域工厂和共享缓存模式。即使
ENABLE\u SELECTIVE
被记录为默认值,我也需要将其精确地设置为该值。Thx Daimon,对于走到这一步的任何人来说,值得注意的是,您需要问题中的两种配置,除了这个答案的配置之外。最好设置
spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
,因为只有这样你才能尊重你的
@javax.persistence.Cacheable
注释。我通过设置这个属性解决了这个问题:hibernate.cache.region.factory\u classI amspring boot 1.5.9.RELEASE获取错误:运行时发生异常。null:InvocationTargetException:创建名为“entityManagerFactory”的bean时出错,该bean在类路径资源[o rg/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]中定义:初始化方法调用失败;嵌套的异常是java。lang.IllegalArgumentException:在我看来,没有枚举常量javax.persistence.SharedCacheMode.javax.persistence.SharedCacheMode.ALLAs,无需显式设置
hibernate.cache.region.factory\u类
hibernate.cache.region.use二级缓存
,因为
org.hibernate.cache.internal.RegionFactoryInitiator
将在只有一个
RegionFactory
实现时自动执行此操作,但建议使用
ehcache.xml
,它绝对不是
logging:
  level:
    org:
      hibernate:
        type: trace
@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) //Provide cache strategy.
public class MyEntity {
  ...
}
public class MyEntityRepository implements JpaRepository<MyEntity, Long> {

  @QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
  List<MyEntity> findBySomething(String something);

}
spring:
  jpa:
    properties:
      hibernate:
        javax:
          cache:
            missing_cache_strategy: create