Spring 数据 jpa 集合不更新
Spring data jpa collection don`t update
您好,我有 2 个实体:部门和用户。
我找到了两个实体并想将一个添加到另一个
但是,如果我将用户添加到部门,则该用户的 Department = null。
如果相反,则 List = null。
如何正确执行此操作?
@Entity
@Table(name = "department")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Department {
@Id
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "uuid2")
@Column(length = 36, nullable = false, updatable = false)
private UUID id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "description", nullable = false)
private String description;
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
private List<User> users = new ArrayList<>();
}
@Entity
@Table(name = "user")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
@Id
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "uuid2")
@Column(length = 36, nullable = false, updatable = false)
private UUID id;
private String firstName;
private String lastName;
private Integer age;
@ManyToOne
private Department department;
@ManyToMany
@JoinTable(
name = "device_devices",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "device_id"))
Set<Device> devices = new HashSet<>();
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equal(id, user.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
}
和服务
@Override
@Transactional
public void addUserToDepartment(UUID departmentId,UUID userId){
Department department = departmentRepository.findById(departmentId).orElseThrow(DepartmentNotFoundException::new);
User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new);
department.getUsers().add(user);
//user.setDepartment(department);
}
在我看来,将用户添加到部门并同时将部门添加到用户是不正确的。他们必须振作起来。
帮助我
双向关系必须由您手动维护,幕后没有魔法可以为您处理。
在服务代码中处理该问题的另一种方法是增强连接属性的设置器来处理该问题,例如在用户端:
public void setDepartment(Department department) {
this.department = department;
department.getUsers().add(this);
}
有关文档,请参阅 here。
这就是你拥有 mappedBy
属性的原因。它提示休眠哪一方将负责这些映射当你有一个双向 ascosiation.
所以考虑你的配置
public class Department {
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
private List<User> users = new ArrayList<>();
...
}
然后只在现场部门的用户上设置映射就足够了
@Override
@Transactional
public void addUserToDepartment(UUID departmentId,UUID userId){
Department department = departmentRepository.findById(departmentId).orElseThrow(DepartmentNotFoundException::new);
User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new);
//department.getUsers().add(user); You don't need this.
user.setDepartment(department); This here is enough for hibernate!
}
但是
正如 hibernate 文档所指出的,为了在方法中正常使用 java,您需要手动更新双方。这意味着,如果您只更新一侧,则更改将在数据库级别保留,但在 java 级别,您的其他实例将不会与这些更改同步。
查看休眠文档中的以下示例(示例 297、示例 298)Hibernate Bi directional mapping normal java usage
您好,我有 2 个实体:部门和用户。
我找到了两个实体并想将一个添加到另一个 但是,如果我将用户添加到部门,则该用户的 Department = null。 如果相反,则 List = null。 如何正确执行此操作?
@Entity
@Table(name = "department")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Department {
@Id
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "uuid2")
@Column(length = 36, nullable = false, updatable = false)
private UUID id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "description", nullable = false)
private String description;
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
private List<User> users = new ArrayList<>();
}
@Entity
@Table(name = "user")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
@Id
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "uuid2")
@Column(length = 36, nullable = false, updatable = false)
private UUID id;
private String firstName;
private String lastName;
private Integer age;
@ManyToOne
private Department department;
@ManyToMany
@JoinTable(
name = "device_devices",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "device_id"))
Set<Device> devices = new HashSet<>();
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equal(id, user.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
}
和服务
@Override
@Transactional
public void addUserToDepartment(UUID departmentId,UUID userId){
Department department = departmentRepository.findById(departmentId).orElseThrow(DepartmentNotFoundException::new);
User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new);
department.getUsers().add(user);
//user.setDepartment(department);
}
在我看来,将用户添加到部门并同时将部门添加到用户是不正确的。他们必须振作起来。 帮助我
双向关系必须由您手动维护,幕后没有魔法可以为您处理。
在服务代码中处理该问题的另一种方法是增强连接属性的设置器来处理该问题,例如在用户端:
public void setDepartment(Department department) {
this.department = department;
department.getUsers().add(this);
}
有关文档,请参阅 here。
这就是你拥有 mappedBy
属性的原因。它提示休眠哪一方将负责这些映射当你有一个双向 ascosiation.
所以考虑你的配置
public class Department {
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
private List<User> users = new ArrayList<>();
...
}
然后只在现场部门的用户上设置映射就足够了
@Override
@Transactional
public void addUserToDepartment(UUID departmentId,UUID userId){
Department department = departmentRepository.findById(departmentId).orElseThrow(DepartmentNotFoundException::new);
User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new);
//department.getUsers().add(user); You don't need this.
user.setDepartment(department); This here is enough for hibernate!
}
但是
正如 hibernate 文档所指出的,为了在方法中正常使用 java,您需要手动更新双方。这意味着,如果您只更新一侧,则更改将在数据库级别保留,但在 java 级别,您的其他实例将不会与这些更改同步。
查看休眠文档中的以下示例(示例 297、示例 298)Hibernate Bi directional mapping normal java usage