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

Spring Boot:事务启动时自动启用Hibernate Session Filter相关问询

关于Hibernate Session与过滤器自动启用的问题解答

1. Spring Boot是否会为每个HTTP请求创建专属的Hibernate Session?

默认情况下,Spring Boot开启**Open Session in View(OSIV)**模式(配置spring.jpa.open-in-view=true为默认值),此时每个HTTP请求会绑定一个独立的Hibernate Session:

  • Session在请求初始化时创建,直到响应返回后才关闭,整个请求周期内的所有数据库操作(包括多个事务)都会复用这个Session。
  • 如果手动关闭OSIV(设置spring.jpa.open-in-view=false),Session的生命周期将与事务绑定:每个@Transactional方法会创建或复用一个Session,一个HTTP请求若包含多个事务,可能对应多个Session,但单事务内共用一个Session。

2. 能否通过回调等方式拦截Session创建以启用Hibernate Filter?

可以,以下是几种可靠的实现方案:

方案一:利用Hibernate Session创建事件监听

通过监听SESSION_CREATED事件,在Session创建时自动启用过滤器:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.SessionCreatedEvent;
import org.hibernate.event.spi.SessionEventListener;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import jakarta.persistence.EntityManagerFactory;

@Component
public class SessionFilterInitializer {

    private final EntityManagerFactory entityManagerFactory;

    public SessionFilterInitializer(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @PostConstruct
    public void initSessionListener() {
        SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
        if (sessionFactory instanceof SessionFactoryImplementor) {
            EventListenerRegistry registry = ((SessionFactoryImplementor) sessionFactory)
                    .getServiceRegistry().getService(EventListenerRegistry.class);
            registry.appendListeners(EventType.SESSION_CREATED, new SessionCreatedListener());
        }
    }

    private static class SessionCreatedListener implements SessionEventListener {
        @Override
        public void sessionCreated(SessionCreatedEvent event) {
            Session session = event.getSession();
            // 启用目标过滤器,可按需设置参数
            session.enableFilter("yourTargetFilter")
                    .setParameter("filterParam", "paramValue");
        }
    }
}

方案二:结合Spring事务同步机制

在事务启动时,通过TransactionSynchronization获取当前Session并启用过滤器,更贴合事务生命周期:

import org.hibernate.Session;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;

@Component
public class TransactionFilterEnabler {

    @PersistenceContext
    private EntityManager entityManager;

    public void enableFilterForCurrentTransaction() {
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void beforeCommit(boolean readOnly) {
                    Session session = entityManager.unwrap(Session.class);
                    session.enableFilter("yourTargetFilter")
                            .setParameter("filterParam", "paramValue");
                }
            });
        }
    }
}

搭配AOP全局拦截所有@Transactional方法,自动执行过滤器启用逻辑:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TransactionAspect {

    private final TransactionFilterEnabler filterEnabler;

    public TransactionAspect(TransactionFilterEnabler filterEnabler) {
        this.filterEnabler = filterEnabler;
    }

    @Before("@annotation(org.springframework.transaction.annotation.Transactional)")
    public void enableFilterBeforeTransaction() {
        filterEnabler.enableFilterForCurrentTransaction();
    }
}

方案三:自定义Hibernate拦截器

实现EmptyInterceptor,在Session创建后触发过滤器启用:

import org.hibernate.EmptyInterceptor;
import org.hibernate.Session;
import org.springframework.stereotype.Component;

@Component
public class FilterEnablingInterceptor extends EmptyInterceptor {

    @Override
    public void postCreateSession(Session session) {
        session.enableFilter("yourTargetFilter")
                .setParameter("filterParam", "paramValue");
    }
}

通过配置类注册该拦截器:

import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.boot.spi.SessionFactoryBuilderFactory;
import org.hibernate.boot.spi.SessionFactoryBuilderImplementor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HibernateConfig {

    @Bean
    public SessionFactoryBuilderFactory sessionFactoryBuilderFactory(FilterEnablingInterceptor interceptor) {
        return defaultBuilder -> {
            defaultBuilder.applyInterceptor(interceptor);
            return defaultBuilder;
        };
    }
}

内容的提问来源于stack exchange,提问作者Massimo Intelisano

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 02:46:19