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

Spring Boot @ManyToMany更新时关联记录被删除问题求助

问题分析与解决方案

核心问题1:双向多对多映射配置错误

你当前的User和AccountLo类都配置了@JoinTable,这会让Hibernate将其判定为两个独立的关联关系,更新操作时会产生逻辑冲突,进而误删关联数据。双向多对多仅需在**一方(主维护方)**配置@JoinTable,另一方通过mappedBy指定关联属性即可。

核心问题2:更新时关联数据未正确保留

@ModelAttribute绑定的User是脱离持久化上下文的新对象,若前端更新时未传递accountLos相关信息,这个列表会是空的。Hibernate执行更新操作时,会默认认为你要移除所有关联,因此删除中间表记录,甚至因映射错误导致实体本身被删除。


步骤1:修正双向多对多映射

修改AccountLo类的多对多配置,移除@JoinTable,改用mappedBy指向User类的关联属性:

public class AccountLo {
    ....
    @ManyToMany(mappedBy = "accountLos", fetch = FetchType.EAGER)
    @Getter @Setter private List<User> users;  
    ....
}

User类的配置保持不变,作为关联的主维护方。

步骤2:更新时保留原有关联数据

修改控制器的saveUser方法,更新用户时先从数据库加载原有实体,保留其关联的AccountLo列表(如果前端未传递新的关联信息):

@PostMapping("/manage_users/save")
public String saveUser(@ModelAttribute("user") User user, @RequestParam("roleRadio") String roleString, Model theModel) {
    List<UserType> userTypes = new ArrayList<>();
    userTypes.add(userTypeService.findById(1));
    user.setUserTypes(userTypes);

    // 若为更新操作,加载原有用户的关联数据
    if (user.getId() != null) {
        User existingUser = userService.findById(user.getId());
        // 保留原有AccountLo关联(若前端未传递新关联)
        user.setAccountLos(existingUser.getAccountLos());
        // 若前端需要更新关联,此处可替换为前端传递的新列表
    }

    userService.save(user);
    return "redirect:/admin/manage_users";
}

额外注意事项

  • 确保userService.save使用Spring Data JPA的save()方法(自动处理新增/更新),而非仅用于新增的persist()。
  • 若需在更新时修改关联的AccountLo,前端需正确传递这些数据的ID或实体信息,后端再做对应合并处理。
  • 避免滥用FetchType.EAGER,业务允许的话改为FetchType.LAZY,可提升性能并减少不必要的关联加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:55:55