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

将@Transactional从Repository移到Service后出现ORA-00900无效SQL语句错误

问题根因与修复方案

核心原因

  • @Modifying是Spring Data JPA专门为Repository层接口方法设计的注解,仅在Repository层生效,放到Service层方法上不会被JPA框架识别。
    当Repository层的删改方法没有@Modifying注解时,JPA会默认将该方法对应的SQL当做查询语句处理,调用JDBC的executeQuery()执行,而delete语句本身不属于查询类SQL,执行时就会抛出ORA-00900: Invalid SQL Statement语法错误。
  • @Transactional注解可以放在Service层做全局事务管控,无需强制放在Repository层。

正确调整方案

保留Repository层方法上的@Modifying注解,@Transactional可以放在Service层即可,两者不冲突。

修正后代码

Repository层代码

@Repository("someRepository")
public interface SomeRepository extends CrudRepository<SomeEntity, String>{
    // @Modifying 必须保留在Repository的修改类方法上
    @Modifying
    @Query(nativeQuery = true, value = "delete from some_table where col = :param")
    int repoDelete(@Param("param") String param);
}

Service层代码

@Service(value = "someService")
public class SomeServiceImpl implements SomeService {
    @Autowired
    SomeRepository repo;

    @Override
    @Transactional
    public void serviceDelete(String id) throws UdhException {
        // Service层不需要加@Modifying注解,框架不会识别
        repo.repoDelete(id);
    }
}

补充说明

如果需要支持Repository层方法单独调用时也能正常开启事务,可以同时在Repository的方法上添加@Transactional注解,默认的REQUIRED事务传播机制会自动复用Service层开启的事务,不会产生冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:24:04