题目描述
使用@ManyToOne如何更新主键
题目来源及自己的思路
用户表和部门表多对一的关系,现在在用户表上使用@ManyToOne,部门表使用了@OneToMany,然后当我想要修改用户的部门时,调用修改接口,传递参数为用户ID和部门ID,请问如何去更新呢?
相关代码
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table (name = "t_dept")
public class Department extends BaseEntity {
@Column(columnDefinition="varchar(20) DEFAULT '' COMMENT '部门中文名'")
private String deptName;
@Column(columnDefinition="varchar(20) DEFAULT '' COMMENT '部门名'")
private String dept;
@Column(columnDefinition="int DEFAULT 0 COMMENT '上级部门ID'")
private Integer parentDeptId;
@OneToMany (mappedBy = "dept",cascade= CascadeType.ALL,fetch= FetchType.LAZY)
private Set< User > users;
@OneToMany (mappedBy = "dept",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
private Set< Role > roles;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "t_user")
public class User extends BaseEntity {
@Column(columnDefinition="varchar(20) DEFAULT '' COMMENT '用户名'",nullable = false)
private String username;
@Column(columnDefinition="varchar(100) DEFAULT '' COMMENT '密码'",nullable = false)
private String password;
@ManyToOne ( cascade = CascadeType.ALL, fetch = FetchType.LAZY )
@JoinColumn ( name = "dept_id" )
private Department dept;
@ManyToOne ( cascade = CascadeType.ALL, fetch = FetchType.LAZY )
@JoinColumn ( name = "role_id" )
private Role role;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserUpdateReq {
@NotNull
private Integer id;
@Length (max=20,min = 8,message = "用户名长度8-20位")
private String username;
@Length(max=16,min = 8,message = "密码长度8-16位")
private String password;
@NotNull
private Integer deptId;
@NotNull
private Integer roleId;
}
你期待的结果是什么?实际看到的错误信息又是什么?
我希望查询出来的结果是用户关联部门信息,例如当传的deptId为2的时候,用户由部门1变成部门2的信息,实际错误是使用了CascadeType会导致对应部门ID信息被变更为null,但是不加CascadType的话会导致用户没有部门信息
###这种直接用语句更新好点
###jpa的双向关联是个大坑,这里建议尽量不要使用双向关联.
这里由于你使用了双向关联,所以必须两边都要相互设置才能达成想要的结果
user.setDept(dept2); // 由于是双向关联,所以这样还不够
userRepository.save(user);
dept2.getUsers().add(user); // 还需要反向关联一遍
deptRepository.save(dept2);
并且你两边都设置了cascade 是非常危险的,说不定哪一天就莫名其妙的数据紊乱.
就不说还有各种序列化循环引用的问题了.
总之不要双向关联!不要双向关联!不要双向关联!