Spring Boot 3迁移后org.hibernate.EmptyInterceptor过时报错如何解决?
EmptyInterceptor过时的问题 你遇到的这个问题是因为Spring Boot 3默认集成了Hibernate 6,而Hibernate 6已经将org.hibernate.EmptyInterceptor标记为过时,官方推荐直接实现org.hibernate.Interceptor接口来替代它。你之前尝试替换成Interceptor却没效果,大概率是因为类名冲突和方法签名不匹配这两个问题,下面一步步帮你解决:
1. 修正类定义与方法签名
首先,你的类名Interceptor和Hibernate的org.hibernate.Interceptor接口重名了,这会导致编译或运行时的冲突,先把类名改成更具辨识度的名字(比如CustomSqlTenantInterceptor)。然后直接实现org.hibernate.Interceptor接口,注意重写的onPrepareStatement方法在新接口里多了一个SharedSessionContractImplementor参数(你可以不用这个参数,只保留核心业务逻辑)。
修正后的代码如下:
import org.hibernate.Interceptor; import org.hibernate.SharedSessionContractImplementor; import org.slf4j.MDC; import org.springframework.util.StringUtils; public class CustomSqlTenantInterceptor implements Interceptor { @Override public String onPrepareStatement(String sql, SharedSessionContractImplementor session) { if (StringUtils.hasLength(sql) && sql.toLowerCase().startsWith("select")) { final String entityName = sql.substring(7, sql.indexOf(".")); final String idEntreprise = MDC.get("idEntreprise"); if (StringUtils.hasLength(entityName) && !entityName.toLowerCase().contains("entreprise") && !entityName.toLowerCase().contains("roles") && StringUtils.hasLength(idEntreprise)) { if (sql.contains("where")) { sql = sql + " and "+entityName+".idEntreprise = "+idEntreprise; } else { sql = sql + " where "+entityName+".idEntreprise = "+idEntreprise; } } } return sql; // 接口默认实现直接返回原SQL,这里直接返回修改后的SQL即可 } }
2. 配置拦截器到Spring Boot
接下来需要把这个自定义拦截器配置到Hibernate中,有两种常用方式:
方式一:通过配置文件直接指定
在application.properties中添加:
spring.jpa.properties.hibernate.session_factory.interceptor=com.yourpackage.CustomSqlTenantInterceptor
(请替换成你实际的包路径)
方式二:通过Spring Bean注入(适合需要依赖注入的场景)
如果你的拦截器需要注入其他Spring管理的Bean,可以定义一个HibernatePropertiesCustomizer的配置类:
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class HibernateConfig { @Bean public HibernatePropertiesCustomizer hibernatePropertiesCustomizer() { return properties -> properties.put("hibernate.session_factory.interceptor", new CustomSqlTenantInterceptor()); } }
额外安全提示
⚠️ 你的代码中直接将idEntreprise拼接到SQL里存在SQL注入风险!建议改用参数绑定的方式,或者使用专业的SQL解析工具(比如JSqlParser)来修改SQL,避免恶意输入导致的安全问题。
内容的提问来源于stack exchange,提问作者Franck TCHIENGUEN

