几天来,我一直在try 将我的旧项目从Springboot 2 / Hibernate 5 / EHCache 2迁移到更新的Java 17 / Springboot 3 / Hibernate 6 / EHCache 3.
当然,我已经阅读了大量文档,try 了许多配置和依赖项设置.我还调试了这些库,以找出问题的原因.
在发布代码的相关部分之前,我想列出我试图解决的问题:
- 项目启动,配置被解析(我通过调试看到了这一点),EHCache侦听器被注册,但是当从数据库获取数据时,它被存储在缓存中,但是侦听器不触发.
- 尽管有1 minute TTL英镑,但储存的物品永远不会过期.
- 通过调试,我看到DemoEntity EHCache配置初始化了两次:从之前的JCache,然后通过Hibernate本身(这个流可能是上述一些问题的根本原因).
我知道在您掌握的信息如此之少的情况下回答问题并不容易,但我相信您能告诉我,我是否在依赖项包含、应用程序配置(application.yaml
)或代码本身方面犯了任何明显的错误.
它遵循相关的代码部分.
提前谢谢您!
pom.xml个
<properties>
<springboot.version>3.1.2</springboot.version>
<ehcache.version>3.10.8</ehcache.version>
<hibernate.version>6.2.2.Final</hibernate.version> <!-- As for the current version of springboot -->
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>${ehcache.version}</version>
<classifier>jakarta</classifier>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
<version>${hibernate.version}</version>
</dependency>
</dependencies>
application.yaml个
spring:
cache:
jcache:
config: file:///app/config/ehcache.xml
jpa:
properties:
hibernate:
cache:
region.factory_class: org.hibernate.cache.jcache.internal.JCacheRegionFactory
use_second_level_cache: true
use_query_cache: true
ehcache.xml个
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.10.xsd"
>
<cache-template name="entitiesDefault">
<expiry>
<ttl unit="minutes">1</ttl>
</expiry>
<listeners>
<listener>
<class>api.demo.springboot.framework.persistence.JpaCacheEventListener</class>
<event-firing-mode>ASYNCHRONOUS</event-firing-mode>
<event-ordering-mode>ORDERED</event-ordering-mode>
<events-to-fire-on>CREATED</events-to-fire-on>
<events-to-fire-on>EVICTED</events-to-fire-on>
<events-to-fire-on>EXPIRED</events-to-fire-on>
<events-to-fire-on>REMOVED</events-to-fire-on>
<events-to-fire-on>UPDATED</events-to-fire-on>
</listener>
</listeners>
<resources>
<heap unit="entries">1000</heap>
</resources>
</cache-template>
<cache-template name="entitiesRelationsDefault">
<expiry>
<ttl unit="minutes">1</ttl>
</expiry>
<listeners>
<listener>
<class>api.demo.springboot.framework.persistence.JpaCacheEventListener</class>
<event-firing-mode>ASYNCHRONOUS</event-firing-mode>
<event-ordering-mode>ORDERED</event-ordering-mode>
<events-to-fire-on>CREATED</events-to-fire-on>
<events-to-fire-on>EVICTED</events-to-fire-on>
<events-to-fire-on>EXPIRED</events-to-fire-on>
<events-to-fire-on>REMOVED</events-to-fire-on>
<events-to-fire-on>UPDATED</events-to-fire-on>
</listener>
</listeners>
<resources>
<heap unit="entries">1000</heap>
</resources>
</cache-template>
<cache-template name="queriesDefault">
<expiry>
<ttl unit="minutes">1</ttl>
</expiry>
<listeners>
<listener>
<class>api.demo.springboot.framework.persistence.JpaCacheEventListener</class>
<event-firing-mode>ASYNCHRONOUS</event-firing-mode>
<event-ordering-mode>ORDERED</event-ordering-mode>
<events-to-fire-on>CREATED</events-to-fire-on>
<events-to-fire-on>EVICTED</events-to-fire-on>
<events-to-fire-on>EXPIRED</events-to-fire-on>
<events-to-fire-on>REMOVED</events-to-fire-on>
<events-to-fire-on>UPDATED</events-to-fire-on>
</listener>
</listeners>
<resources>
<heap unit="entries">1000</heap>
</resources>
</cache-template>
<cache
alias="default-update-timestamps-region"
>
<expiry>
<ttl unit="minutes">1</ttl>
</expiry>
<listeners>
<listener>
<class>api.demo.springboot.framework.persistence.JpaCacheEventListener</class>
<event-firing-mode>ASYNCHRONOUS</event-firing-mode>
<event-ordering-mode>ORDERED</event-ordering-mode>
<events-to-fire-on>CREATED</events-to-fire-on>
<events-to-fire-on>EVICTED</events-to-fire-on>
<events-to-fire-on>EXPIRED</events-to-fire-on>
<events-to-fire-on>REMOVED</events-to-fire-on>
<events-to-fire-on>UPDATED</events-to-fire-on>
</listener>
</listeners>
<resources>
<heap unit="entries">1000</heap>
</resources>
</cache>
<cache
alias="default-query-results-region"
uses-template="queriesDefault"
/>
<cache
alias="DemoEntity"
uses-template="entitiesDefault"
>
<value-type>api.demo.springboot.application.persistence.entities.DemoEntity</value-type>
</cache>
</config>
DemoEntity.java个
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.springframework.cache.annotation.Cacheable;
import java.io.Serializable;
@Data
@Entity
@Table(name = "DEMO_TABLE")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class DemoEntity implements Serializable {
private static final long serialVersionUID = 0L;
@Id
@Column(name = "ID")
private Integer id;
@Column(name = "DESCRIPTION")
private String description;
}
JpaCacheEventListener.java个
import lombok.extern.slf4j.Slf4j;
import org.ehcache.event.CacheEvent;
import org.ehcache.event.CacheEventListener;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class JpaCacheEventListener implements CacheEventListener<Object, Object> {
@Override
public void onEvent(CacheEvent event) {
if (log.isTraceEnabled()) {
log.trace(
"{ type: {}, key: {} }",
event.getType(),
event.getKey()
);
}
}
}