上下文更新与各协会
我有两个@OneToMany
和@ManyToMany
关联的实体的部分设置实体。我从前端收到一个对象,其中只设置了一些属性(而不是关联)。目标是更新数据库中该实体的数据。
问题
接收的对象是一个分离的实体,所以当它的更新,合并操作被调用。由于没有设置关联,@ManyToMany
部分被删除,但不是@OneToMany
(因为没有级联)。一种选择是从数据库中检索实体,加载@ManyToMany
关联,然后将所有属性从前端对象复制到该实体,然后合并,坚持对象,但我不确定这是否是最佳做法。
代码
在数据库中创建一个完整的对象
Course hibernate = new Course();
hibernate.setName("Hibernate");
Course java = new Course();
java.setName("Java");
entityManager.persist(hibernate);
entityManager.persist(java);
Address address = new Address();
address.setName("White House");
entityManager.persist(address);
Student student = new Student();
student.setName("Sydney");
student.addAddress(address);
student.addCourse(hibernate);
student.addCourse(java);
entityManager.persistAndFlush(student);
entityManager.clear();
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence
Hibernate: insert into course (name, id) values (?, ?)
Hibernate: insert into course (name, id) values (?, ?)
Hibernate: insert into address (name, student_id, id) values (?, ?, ?)
Hibernate: insert into student (name, id) values (?, ?)
Hibernate: update address set name=?, student_id=? where id=?
Hibernate: insert into student_course (students_id, courses_id) values (?, ?)
Hibernate: insert into student_course (students_id, courses_id) values (?, ?)
从前端
Student partialStudent = new Student();
partialStudent.setId(student.getId());
partialStudent.setName("Sydney Updated");
Student attachedPartialStudent = entityManager.merge(partialStudent);
entityManager.persistAndFlush(attachedPartialStudent);
entityManager.clear();
这部分坚持的对象生成一个DELETE SQL
Hibernate: select student0_.id as id1_41_0_, student0_.name as name2_41_0_ from student student0_ where student0_.id=?
Hibernate: select courses0_.students_id as students1_42_0_, courses0_.courses_id as courses_2_42_0_, course1_.id as id1_13_1_, course1_.name as name2_13_1_ from student_course courses0_ inner join course course1_ on courses0_.courses_id=course1_.id where courses0_.students_id=?
Hibernate: update student set name=? where id=?
Hibernate: delete from student_course where students_id=?
学生实体:
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@NotNull
@Column(name = "name", nullable = false)
private String name;
@OneToMany(mappedBy = "student")
private Set<Address> addresses = new HashSet<>();
@ManyToMany
@JoinTable(name = "student_course")
private Set<Course> courses = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
public void addCourse(Course course) {
courses.add(course);
course.getStudents().add(this);
}
public void removeCourse(Course course) {
courses.remove(course);
course.getStudents().remove(this);
}
public Set<Address> getAddresses() {
return addresses;
}
public void setAddresses(Set<Address> addresses) {
this.addresses = addresses;
}
public void addAddress(Address address) {
addresses.add(address);
address.setStudent(this);
}
public void removeAddress(Address address) {
addresses.remove(address);
address.setStudent(null);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return Objects.equals(id, student.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
课程实体:
@Entity
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@NotNull
@Column(name = "name", nullable = false)
private String name;
@ManyToMany(mappedBy = "courses")
private Set<Student> students = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
public void addStudent(Student student) {
students.add(student);
student.getCourses().add(this);
}
public void removeStudent(Student student) {
students.remove(student);
student.getCourses().remove(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Course)) return false;
Course course = (Course) o;
return Objects.equals(id, course.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
地址实体:
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@NotNull
@Column(name = "name", nullable = false)
private String name;
@ManyToOne
private Student student;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Address)) return false;
Address address = (Address) o;
return Objects.equals(id, address.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}