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
相关产品推荐
相关产品推荐

