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

Spring Boot JPA如何调用无参无返回值的MySQL存储过程

核心错误点
  • Repository中存储过程方法定义为static且自带方法体:Spring Data JPA 只会为接口的非静态抽象方法生成代理实现,静态方法属于接口自身方法,不会触发数据库调用逻辑。
  • 方法返回值与存储过程不匹配:你的存储过程无入参、无返回值,定义返回boolean类型完全不符合映射规则。
  • Service层直接调用接口静态方法:没有注入Spring管理的Repository代理Bean,根本走不到JPA的执行链路。
  • 缺少修改操作标记与事务配置:存储过程执行表数据更新,属于写操作,没有@Modifying标记和事务支持会直接执行失败。
正确实现代码

1. 实体类配置(两种方案二选一即可)

方案一:使用@NamedStoredProcedureQuery显式声明

@Entity
@NamedStoredProcedureQuery(
    name = "PickingItem.spAssignPairNo",
    procedureName = "spAssignPairNo"
)
@Table(name = "picking_item")
@lombok.Data
public class PickingItem implements Serializable {
    // 原有实体字段保持不变
}

方案二:无需在实体类加注解,直接在Repository层指定存储过程名,代码更简洁。

2. Repository层修正

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;

@Repository
public interface PickingItemRepository extends JpaRepository<PickingItem, Integer> {
    List<PickingItem> findByPickingOrderId(Integer pickingOrderId); 
    Optional<PickingItem> findByPickingOrderIdAndMaterialId(Integer pickingOrderId, Integer materialId); 

    // 如果用方案一(实体类加注解),name和@NamedStoredProcedureQuery的name保持一致
    // @Procedure(name = "PickingItem.spAssignPairNo")
    // 如果用方案二(不加实体类注解),直接指定procedureName即可
    @Procedure(procedureName = "spAssignPairNo")
    @Modifying // 标记为数据修改操作
    void spAssignPairNo(); // 不要加static,不要写方法体,返回值设为void
}

3. Service层修正

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;

@Service
public class PickingOrderService {
    // 注入Spring管理的Repository实现Bean,禁止静态调用
    @Resource
    private PickingItemRepository pickingItemRepository;

    @Transactional(rollbackFor = Exception.class) // 写操作必须加事务,异常时自动回滚
    public void spAssignPairNoExplicit() {
        pickingItemRepository.spAssignPairNo();
    }
}
注意事项

启动项目后调用spAssignPairNoExplicit()方法即可正常触发存储过程执行,直接对Picking_Item表完成数据更新。如果执行报错优先检查:

  • 数据库账号是否有该存储过程的执行权限
  • 存储过程名是否和数据库中定义的完全一致(MySQL特殊大小写敏感配置场景下需要完全匹配)
  • 不要在测试类不加事务配置直接调用写操作方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:02:16