本文介紹了JPA持久化與現有實體有關系的新實體的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我有兩個具有@ManyToMany
關系的實體,讓我們舉一個常見的示例學生和課程,我正在持久化一個新課程和一個學生列表,如果列表中有一個新學生,它應該級聯新的學生,如果它已經存在,它應該更新它。
對于新學生和新課程的情況,它工作得很好,但是對于新課程和現有學生,我從數據庫中拋出了一個唯一的約束違反。關系如下。
@Entity
@Table
public class Course implements Serializable {
@Id
@Column(name = "CRS_ID")
@SequenceGenerator(name = "rcrsSeq", sequenceName = "CRS_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "rcrsSeq")
private Long id;
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.REFRESH,
CascadeType.DETACH
})
@JoinTable(name = "student_courses",
uniqueConstraints = @UniqueConstraint(columnNames = {"STU_ID", "CRS_ID"}),
joinColumns = {@JoinColumn(name = "CRS_ID")},
inverseJoinColumns = {@JoinColumn(name = "STU_ID")}
)
private List<Student> students;
//getters and setters
}
@Entity
@Table(uniqueConstaints = @UniqueConstraint(columnNames = {"username"}))
public class Student implements Serializable {
@Id
@Column(name = "STU_ID")
@SequenceGenerator(name = "rstuSeq", sequenceName = "STU_SEQ", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "rstuSeq")
private Long id;
@ManyToMany(mappedBy = "students")
private List<Course> courses;
private String userName;
//getters and setters
// equals + hashcode based on userName
}
在持久化之前,我嘗試使用entityManager查找一個學生,如果該學生存在,則使用該實例而不是新的學生實例。這也不起作用,它仍然嘗試執行插入而不是更新
推薦答案
您寫的
但是,在新課程和現有學員的情況下,我會從數據庫中拋出唯一的約束沖突。
如果要持久化新的Course
對象和現有的Student
對象,應執行以下操作:
創建Course
的實例:
Course course = new Course(...);
獲取現有Student
:
Student student = entityManager.find(Student.class, id_of_student);
連接關系如下:
course.getStudents.add(student);
student.getCourse().add(course);
實際上您應該調用entityManager.persist()
來保存新實體。但在這種情況下,這將不起作用,因為student
不是新的實體實例,并且persist()
不會保存現有的實體實例。因此,您可以使用entityManager.merge()
,即使它在語義上不正確(因為merge
應該用于分離的實體):
entityManager.merge(course);
為了使其正常工作,您應該調用事務中的所有實體管理器方法。
這篇關于JPA持久化與現有實體有關系的新實體的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,