请求提供Hibernate二级缓存启用的完整正确步骤及当前报错问题解决方法
先给你搞定当前的报错,再一步步教你正确配置Hibernate 6的二级缓存——你的问题根源主要是依赖版本不兼容和配置项选错了。
一、先解决javax.transaction.SystemException报错
这个错误是因为你引入了过时的hibernate-ehcache预发布版本(6.0.0.Alpha7),它依赖的是旧的javax.transaction包,但你现在用的Hibernate 6是基于Jakarta EE规范的,用的是jakarta.transaction,两者直接冲突。而且Hibernate 6早就不推荐用旧的hibernate-ehcache模块了,官方推荐用hibernate-jcache配合JCache实现(比如Ehcache 3)。
1. 修正build.sbt依赖
删掉org.hibernate.orm % "hibernate-ehcache" % "6.0.0.Alpha7"这一行,同时把Hibernate相关模块的版本对齐(避免版本不一致引发隐性问题),修正后的依赖片段如下:
"org.hibernate.orm" % "hibernate-core" % "6.6.3.Final", "org.hibernate.validator" % "hibernate-validator" % "8.0.0.Final", "org.glassfish" % "jakarta.el" % "5.0.0-M1" % Test, "io.agroal" % "agroal-pool" % "2.5", "org.hibernate.orm" % "hibernate-agroal" % "6.6.3.Final", // 和core版本对齐 "com.mysql" % "mysql-connector-j" % "9.1.0", "jakarta.el" % "jakarta.el-api" % "6.0.1", "com.sun.el" % "el-ri" % "3.0.4", "org.hibernate.orm" % "hibernate-jcache" % "6.6.3.Final", // 和core版本对齐 "org.ehcache" % "ehcache" % "3.10.8", "jakarta.xml.bind" % "jakarta.xml.bind-api" % "4.0.2", "org.glassfish.jaxb" % "jaxb-runtime" % "4.0.5", "jakarta.transaction" % "jakarta.transaction-api" % "2.0.1",
2. 修正Hibernate配置代码
你之前用的EhCacheRegionFactory是旧Ehcache 2的工厂类,换成JCache对应的JCacheRegionFactory,同时清理重复的配置项(比如你重复设置了hibernate.hbm2ddl.auto),修正后的代码:
val config = new Configuration() .addAnnotatedClass(classOf[Server]) .addAnnotatedClass(classOf[Chat]) .addAnnotatedClass(classOf[User]) .setProperty(JAKARTA_JDBC_URL, "jdbc:mysql://localhost:3306/hydra_data") .setProperty(JAKARTA_JDBC_USER, sqlUser) .setProperty(JAKARTA_JDBC_PASSWORD, sqlPass) .setProperty("hibernate.hbm2ddl.auto", "update") // Agroal连接池配置 .setProperty("hibernate.agroal.maxSize", "20") // 二级缓存核心配置 .setProperty("hibernate.cache.use_second_level_cache", "true") // 显式开启二级缓存 .setProperty("hibernate.cache.use_query_cache", "true") // 开启查询缓存(按需开启) .setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.jcache.JCacheRegionFactory") .setProperty("hibernate.javax.cache.provider", "org.ehcache.jsr107.EhcacheCachingProvider") .setProperty("hibernate.javax.cache.uri", "classpath:ehcache.xml") // 可选:指定自定义缓存配置文件 sessionFactory = Option(config.buildSessionFactory())
二、完整的二级缓存启用步骤
搞定报错后,按照以下步骤完成配置:
1. 给实体类开启缓存
在需要缓存的实体类上添加@Cache注解,选择合适的缓存并发策略(根据业务场景选,比如READ_WRITE适合读写频繁的场景,READ_ONLY适合只读数据):
import jakarta.persistence.Entity; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Server { // 你的实体类字段和方法 }
同样给Chat、User类加上这个注解。
2. 自定义Ehcache配置(可选)
如果需要调整缓存的过期时间、内存限制等,在src/main/resources下创建ehcache.xml文件,示例配置:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ehcache.org/v3" xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd"> <!-- 默认缓存模板 --> <cache-template name="default"> <expiry> <ttl unit="minutes">10</ttl> <!-- 缓存10分钟后过期 --> </expiry> <heap unit="entries">1000</heap> <!-- 堆内存最多存1000条数据 --> </cache-template> <!-- 对应实体类的缓存区域,别名要和实体类全限定名一致 --> <cache alias="com.yourpackage.Server" uses-template="default"/> <cache alias="com.yourpackage.Chat" uses-template="default"/> <cache alias="com.yourpackage.User" uses-template="default"/> <!-- 查询缓存的专用区域 --> <cache alias="org.hibernate.cache.internal.QueryResultsRegion" uses-template="default"/> <cache alias="org.hibernate.cache.internal.UpdateTimestampsRegion" uses-template="default"/> </config>
3. 验证缓存生效
启动应用后,你可以通过Hibernate的日志(开启org.hibernate.cache的DEBUG级别)查看缓存的命中情况,或者重复查询同一个实体,观察数据库查询次数是否减少,来验证缓存是否正常工作。
备注:内容来源于stack exchange,提问作者Kris Rice

