You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3迁移后org.hibernate.EmptyInterceptor过时报错如何解决?

解决Spring Boot 3中Hibernate 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:25:16