JPA如何同时保存关联的User与UserLogin实体,解决外键userid为空报错
问题根因
你配置的是双向一对一关联,User是关联的被维护端(mappedBy = "user"指定由UserLogin的user属性维护关联关系),外键userid存储在UserLogin对应的表中。JPA只会根据维护端的属性值写入外键,你当前的代码没有给UserLogin的user属性赋值,因此会触发外键为空的报错。
调整方案
1. 同步双向关联关系(必须修改)
在保存User之前,手动给user关联的userLogin属性赋值当前user对象即可解决问题,修改后的代码如下:
@Transactional public User register(User user) { Set<UserRole> roleSet = new HashSet<>(); UserRole role = new UserRole(); // 配置默认角色 role.setRole_name("ROLE_NHANVIEN"); role.setId(4L); roleSet.add(role); // 后续将执行密码加密 user.setRoles(roleSet); // 新增代码:同步双向关联,给维护端赋值 user.getUserLogin().setUser(user); log.info(user.getUserLogin().getUsername()); return userRepository.save(user); }
2. 冗余级联配置优化(可选修改)
UserLogin作为关联维护端,不需要配置回指User的级联操作,避免产生不必要的级联更新/删除风险,建议调整UserLogin的关联配置:
class UserLogin { // 移除cascade = CascadeType.ALL,不需要从UserLogin级联操作主实体User @OneToOne @JoinColumn(name = "userid", referencedColumnName = "id") private User user; }
3. 角色关联逻辑优化(可选修改)
当前手动new的UserRole属于游离态对象,如果User和UserRole的关联配置了级联校验,可能会触发游离对象异常,建议改为从数据库查询已存在的角色对象:
// 替换原手动new UserRole的逻辑即可 UserRole role = roleRepository.getReferenceById(4L);
内容的提问来源于stack exchange,提问作者Steve Dng
相关产品推荐
相关产品推荐

