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

Spring Boot3/Hibernate6下@Transactional无法启动事务问题排查

Spring Boot 3/Hibernate 6 事务注解失效排查与解决

问题情况

迁移到Spring Boot 3 + Hibernate 6环境后,Hibernate能正常解析实体、仓库,数据库连接也没问题,但@Transactional注解就是启动不了事务。

测试代码

@Component
public class Test {

  @Autowired
  private EntityManagerFactory entityManager;

  @Transactional
  public void test() {
    Session s = entityManager.unwrap(SessionFactory.class).getCurrentSession();
    s.createQuery("FROM sometable").list();
  }
}

报错信息

Caused by: org.hibernate.HibernateException: Calling method 'createQuery' is not valid without an active transaction (Current status: NOT_ACTIVE)
    at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:341)

当前配置

事务配置类

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.somepackage")
@EntityScan(basePackages="com.somepackage")
public class TransactionConfig {
...
}

application.properties中的会话配置

...
spring.jpa.properties.hibernate.current_session_context_class=thread
...

删掉这个会话配置后,又报新错:

Caused by: org.hibernate.HibernateException: No CurrentSessionContext configured

补充测试结果

  • 改用@PersistenceUnit注入EntityManagerFactory,还是一样的无活跃事务错误。
  • 直接调用继承JpaRepository的类能跑,但会新建事务,完全无视父级的@Transactional。

解决办法

1. 删掉自定义的会话上下文配置

Spring Boot整合Hibernate时,会自动把CurrentSessionContext设为SpringSessionContext,手动加thread配置会覆盖这个逻辑,导致Spring的事务管理没法把会话绑定到事务里,直接删掉spring.jpa.properties.hibernate.current_session_context_class=thread就行。

2. 换用EntityManager注入

别直接用EntityManagerFactory,改用@PersistenceContext注入EntityManager,Spring会自动把它关联到当前事务的会话:

@Component
public class Test {

  @PersistenceContext
  private EntityManager entityManager;

  @Transactional
  public void test() {
    Session s = entityManager.unwrap(Session.class);
    s.createQuery("FROM sometable").list();
  }
}

3. 确保事务注解被Spring代理生效

  • 保证Test类被Spring扫描到(已经加了@Component,没问题)。
  • 别在类内部直接调用@Transactional方法,Spring代理只对外部调用生效。
  • 如果用JDK动态代理,要确保类实现了接口;或者开启CGLIB代理(Spring Boot默认已经开了),可以在配置类里显式设置:
@EnableTransactionManagement(proxyTargetClass = true)

4. 调整JpaRepository的事务传播行为

直接调用JpaRepository方法时,它自带的事务注解会覆盖父级事务。要是想让它沿用父级事务,需要在自定义仓库接口里重新声明方法,并指定事务传播属性为SUPPORTS:

public interface SomeRepository extends JpaRepository<SomeEntity, Long> {
    @Transactional(propagation = Propagation.SUPPORTS)
    List<SomeEntity> findAll();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:31:37