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

配置JpaTransactionManager后执行删除查询仍抛TransactionRequiredException

问题原因及修复方案

核心问题1:手动创建EntityManager,脱离Spring事务管控

你在test方法里通过dbConfig.getEntityManagerFactory().createEntityManager()手动创建了新的EntityManager,这个实例不在Spring@Transactional注解开启的事务范围内。Spring的事务管理只对它自身注入的EntityManager实例生效,手动创建的EntityManager完全不受其管控,因此执行更新/删除操作时会抛出事务缺失异常。

核心问题2:DBConfig存在重复创建EntityManagerFactory的错误

在myTransactionManager()方法中,你调用getLocalContainerEntityManagerFactoryBean()重新创建了一个LocalContainerEntityManagerFactoryBean实例,这会导致事务管理器使用的EntityManagerFactory,和getEntityManagerFactory()返回的实例不是同一个,进一步造成事务上下文不匹配。

另外代码里还有个低级错误:LocalContainerEntityManagerFactoryBean.setPersistenceUnitName("PERSISTENCE_UNIT");是静态调用,但setPersistenceUnitName是实例方法,应该改为localContainerEntityManagerFactoryBean.setPersistenceUnitName("PERSISTENCE_UNIT");


具体修复步骤

1. 修正DBConfig配置,确保EntityManagerFactory单例

@Configuration
@EnableTransactionManagement
class DBConfig{

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        
        Properties properties = new Properties();
        properties.put("hibernate.dialect", "org.hibernate.dialect.DB2Dialect");
        properties.put("hibernate.show_sql", true);
        properties.put("hibernate.jdbc.batch_size", 5000);
        properties.put("hibernate.hbm2ddl.auto", "");
        properties.put("hibernate.id.new_generator_mappings", false); // 修正拼写错误:nappings → mappings
        
        em.setJpaProperties(properties);
        em.setPackagesToScan("**"); // 建议替换为具体实体包路径,比如com.yourproject.entity
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        em.setDataSource(getDB2DataSource("<DB_SERVER_NAME>"));
        em.setPersistenceUnitName("PERSISTENCE_UNIT"); // 修正为实例方法调用
        em.afterPropertiesSet();
        
        return em;
    }

    @Bean("myTransactionManager")
    public JpaTransactionManager myTransactionManager(EntityManagerFactory entityManagerFactory) {
        // 直接注入Spring管理的EntityManagerFactory,避免重复创建
        return new JpaTransactionManager(entityManagerFactory);
    }

    // 保留你的数据源实现方法
    private DataSource getMSSQLDataSource(String DBServerName) {
        // 你的MSSQL数据源逻辑
    }

    private DataSource getDB2DataSource(String DBServerName) {
        // 你的DB2数据源逻辑
    }
}

2. 修改Test类,使用Spring注入的EntityManager

@Component
public class Test {

    @PersistenceContext(unitName = "PERSISTENCE_UNIT") // 和配置中的持久化单元名一致
    private EntityManager entityManager;

    @Transactional("myTransactionManager") 
    public void test() {
        Query query = entityManager.createNativeQuery("<Some Delete Query>");
        query.executeUpdate(); // 现在会在Spring事务上下文内执行
    }
}

额外注意事项

  • 永远不要手动创建EntityManager/EntityManagerFactory,依赖Spring的依赖注入获取受事务管理的实例。
  • setPackagesToScan("**")会扫描所有包,可能拖慢启动速度,建议指定具体的实体类包路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 14:18:26