Spring 使用 JCache 启动 2.0 Hibernate 5 EhCache 3
Spring Boot 2.0 Hibernate 5 EhCache 3 with JCache
我正在尝试将带有 EhCache 的 Hibernate 设置为二级缓存,但 TTL 不工作。
这是我的依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
这是我的 YAML 配置:
spring:
jpa:
show-sql: true
properties:
hibernate:
dialect: Dialect
cache:
use_second_level_cache: true
region.factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
use_query_cache: true
cache:
jcache:
config: classpath:ehcache.xml
下面是我的实体 class 的配置方式:
@Entity
@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class PersonEntity {
//
}
实体的 JpaRepository:
public interface PersonRepository extends JpaRepository<PersonEntity, Integer> {
@org.springframework.data.jpa.repository.QueryHints({
@javax.persistence.QueryHint(name = "org.hibernate.cacheable", value = "true")
})
List<PersonEntity> findByName(String name);
}
我已经将缓存配置为在 2 秒后过期,但是调用 findByName
仍然使用缓存(在第一个之后没有打印 SQL 查询)。
这是 ehcache.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://www.ehcache.org/v3">
<cache-template name="simple">
<expiry>
<ttl>2</ttl>
</expiry>
<heap>100</heap>
</cache-template>
<cache alias="com.sample.PersonEntity" uses-template="simple"/>
</config>
编辑:
我已经做了一些调试。我在 org.ehcache.jsr107.ExpiryPolicyToEhcacheExpiry
:
中添加了一个断点
javax.cache.expiry.Duration duration = this.expiryPolicy.getExpiryForCreation();
由于某种原因,此持续时间是无限的。那么也许配置设置不正确?我知道 xml 正在被读取,因为当我使它无效时(例如通过删除堆标记)我得到一个错误。
当您在实体顶部设置 @Cacheable
注释时,它会创建一个区域,其中 KEY
是实体的 ID
,Value
是实体。上面的意思是,如果您通过 ID
键访问,您将命中缓存。如果您使用 spring 数据和 findById,它将命中缓存。如果您创建一个方法 findByName,则访问将不是按键 trerefore,因此它不会命中您的 Cacheable
注释定义的缓存区域。另一方面,它会命中查询缓存,但查询缓存位于完全不同的区域。从您的配置来看,您还没有在 all.For 配置查询缓存,此方法根本无法命中任何缓存,您需要使用此 属性:
添加它
spring:jpa:properties:hibernate:cache:use_query_cache: true
或者,您可以在存储库方法之上指定@Cacheable,这样可以定义一个新区域。
您可以配置默认缓存,这应该捕获 StandardQueryCahache。
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600">
</defaultCache>
在 EhCache2 中,您可以通过此元素配置标准查询缓存:
<cache
name="org.hibernate.cache.internal.StandardQueryCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600">
但不确定它在 ehcache 3 中的表现如何。我相信它应该是一样的,因为 StandartQueryCache class 是 hibernate 包的一部分而不是 ehcache 包的一部分。
我也觉得你需要设置
hibernate.javax.cache.provider = org.ehcache.jsr107.EhcacheCachingProvider
我想我找到了问题的原因 - 您没有指定 ehcache.xml
文件的位置:
spring:
jpa:
properties:
hibernate:
javax.cache:
provider: org.ehcache.jsr107.EhcacheCachingProvider
uri: classpath:ehcache.xml
cache:
use_second_level_cache: true
region.factory_class: jcache
use_query_cache: true
在这种情况下,Hibernate 使用默认配置创建缓存。我的演示项目日志中的一个片段:
17:15:19 WARN [main] org.hibernate.orm.cache: HHH90001006: Missing cache[user] was created on-the-fly. The created cache will use a provider-specific default configuration: make sure you defined one. You can disable this warning by setting 'hibernate.javax.cache.missing_cache_strategy' to 'create'.
我正在尝试将带有 EhCache 的 Hibernate 设置为二级缓存,但 TTL 不工作。
这是我的依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
这是我的 YAML 配置:
spring:
jpa:
show-sql: true
properties:
hibernate:
dialect: Dialect
cache:
use_second_level_cache: true
region.factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
use_query_cache: true
cache:
jcache:
config: classpath:ehcache.xml
下面是我的实体 class 的配置方式:
@Entity
@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class PersonEntity {
//
}
实体的 JpaRepository:
public interface PersonRepository extends JpaRepository<PersonEntity, Integer> {
@org.springframework.data.jpa.repository.QueryHints({
@javax.persistence.QueryHint(name = "org.hibernate.cacheable", value = "true")
})
List<PersonEntity> findByName(String name);
}
我已经将缓存配置为在 2 秒后过期,但是调用 findByName
仍然使用缓存(在第一个之后没有打印 SQL 查询)。
这是 ehcache.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://www.ehcache.org/v3">
<cache-template name="simple">
<expiry>
<ttl>2</ttl>
</expiry>
<heap>100</heap>
</cache-template>
<cache alias="com.sample.PersonEntity" uses-template="simple"/>
</config>
编辑:
我已经做了一些调试。我在 org.ehcache.jsr107.ExpiryPolicyToEhcacheExpiry
:
javax.cache.expiry.Duration duration = this.expiryPolicy.getExpiryForCreation();
由于某种原因,此持续时间是无限的。那么也许配置设置不正确?我知道 xml 正在被读取,因为当我使它无效时(例如通过删除堆标记)我得到一个错误。
当您在实体顶部设置 @Cacheable
注释时,它会创建一个区域,其中 KEY
是实体的 ID
,Value
是实体。上面的意思是,如果您通过 ID
键访问,您将命中缓存。如果您使用 spring 数据和 findById,它将命中缓存。如果您创建一个方法 findByName,则访问将不是按键 trerefore,因此它不会命中您的 Cacheable
注释定义的缓存区域。另一方面,它会命中查询缓存,但查询缓存位于完全不同的区域。从您的配置来看,您还没有在 all.For 配置查询缓存,此方法根本无法命中任何缓存,您需要使用此 属性:
spring:jpa:properties:hibernate:cache:use_query_cache: true
或者,您可以在存储库方法之上指定@Cacheable,这样可以定义一个新区域。
您可以配置默认缓存,这应该捕获 StandardQueryCahache。
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600">
</defaultCache>
在 EhCache2 中,您可以通过此元素配置标准查询缓存:
<cache
name="org.hibernate.cache.internal.StandardQueryCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600">
但不确定它在 ehcache 3 中的表现如何。我相信它应该是一样的,因为 StandartQueryCache class 是 hibernate 包的一部分而不是 ehcache 包的一部分。
我也觉得你需要设置
hibernate.javax.cache.provider = org.ehcache.jsr107.EhcacheCachingProvider
我想我找到了问题的原因 - 您没有指定 ehcache.xml
文件的位置:
spring:
jpa:
properties:
hibernate:
javax.cache:
provider: org.ehcache.jsr107.EhcacheCachingProvider
uri: classpath:ehcache.xml
cache:
use_second_level_cache: true
region.factory_class: jcache
use_query_cache: true
在这种情况下,Hibernate 使用默认配置创建缓存。我的演示项目日志中的一个片段:
17:15:19 WARN [main] org.hibernate.orm.cache: HHH90001006: Missing cache[user] was created on-the-fly. The created cache will use a provider-specific default configuration: make sure you defined one. You can disable this warning by setting 'hibernate.javax.cache.missing_cache_strategy' to 'create'.