You need to enable JavaScript to run this app. Spring中Worker与Speciality多对多关联POST请求实现方案咨询
优惠活动
大模型
产品
解决方案
定价
更多

Spring中Worker与Speciality多对多关联POST请求实现方案咨询

实现步骤

第一步:修正实体类关联配置错误

现有代码存在两处配置错误会导致关联异常,优先修正:

  • Speciality类的多对多关联mappedBy属性配置错误,mappedBy需填写对方实体类中关联属性的名称,而非数据库字段名:
// 修正前
@ManyToMany(mappedBy = "speciality_id")
private Set<Worker> workers = new HashSet<>();

// 修正后
@ManyToMany(mappedBy = "specialities")
@JsonIgnore // 新增该注解避免序列化Worker时出现循环引用问题
private Set<Worker> workers = new HashSet<>();
  • Worker类的多对多级联配置移除CascadeType.PERSIST,避免误触发Speciality的新增逻辑:
// 修正前
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST })

// 修正后
@ManyToMany(cascade = CascadeType.MERGE)

第二步:Controller层调整逻辑

首先在WorkerController中注入SpecialityRepository,后续用于查询已存在的Speciality实例,不直接使用前端传入的Speciality对象,避免非法修改Speciality数据。
修改后的POST接口代码如下:

@RestController
@RequestMapping("/api")
public class WorkerController {

    @Autowired
    private WorkerRepository workerRepository;
    // 新增注入SpecialityRepository
    @Autowired
    private SpecialityRepository specialityRepository;

    @PostMapping("/worker")
    public ResponseEntity<Worker> createWorker(@RequestBody Worker worker) {
        try {
            // 处理关联的Speciality:只关联数据库已存在的记录
            Set<Speciality> existSpecialities = new HashSet<>();
            for (Speciality reqSpeciality : worker.getSpecialities()) {
                // 方式1:用getReferenceById直接获取代理对象,无需查询数据库,适合确定SpecialityId一定存在的场景
                Speciality existSpeciality = specialityRepository.getReferenceById(reqSpeciality.getSpeciality_id());
                
                // 方式2:如果需要校验Speciality是否存在,改用findById,不存在直接返回参数错误
                // Optional<Speciality> specialityOpt = specialityRepository.findById(reqSpeciality.getSpeciality_id());
                // if (specialityOpt.isEmpty()) {
                //     return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
                // }
                // Speciality existSpeciality = specialityOpt.get();
                
                existSpecialities.add(existSpeciality);
            }

            // 构建要保存的Worker对象
            Worker _worker = new Worker(
                worker.getName(),
                worker.getSurname(),
                worker.getEmail(),
                worker.getPhoneNumber(),
                existSpecialities, // 替换为查询到的已存在Speciality集合
                worker.getCollege(),
                worker.getFaculty()
            );
            
            workerRepository.save(_worker);
            return new ResponseEntity<>(_worker, HttpStatus.CREATED);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

前端请求示例

前端调用接口时,specialities字段只需要传每个已选Speciality的speciality_id即可,无需传其他Speciality属性,请求JSON示例:

{
  "name": "张三",
  "surname": "张",
  "email": "zhangsan@xxx.com",
  "phoneNumber": "13xxxxxxxxx",
  "specialities": [
    {"speciality_id": 1},
    {"speciality_id": 3}
  ],
  "college": {"college_id": 2},
  "faculty": {"faculty_id": 5}
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 08:42:02