我有两个具有 @ManyToMany
关系的实体,让我们以学生和类(class)为例,如果列表中有新学生,我将保留一个包含学生列表的新类(class)它应该级联新的,如果存在它应该更新它。
对于新学生和新类(class),它工作得很好,但对于新类(class)和现有学生,我会从数据库中抛出一个唯一的约束违规。关系类似于下面。
@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
}
在坚持之前,我尝试使用实体管理器查找学生,如果该学生存在,则使用该实例而不是新的学生实例。这也不起作用,它仍然尝试执行插入而不是更新
最佳答案
你写了
in the case of a new course and an existing student however I get a unique constraint violation being thrown from the database.
如果您想保留新的 Course
对象和现有的 Student
对象,您应该执行以下操作:
创建
类(class)
的实例:Course course = new Course(...);
获取现有
学生
: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);
为了使其工作,您应该调用事务中的所有实体管理器方法。
关于java - JPA 持久保存与现有实体有关系的新实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47139907/