繁体   English   中英

JPA坚持与现有实体关系的新实体

[英]JPA persist new entity with relationship to existing entity

我有两个与@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对象,则应执行以下操作:

  1. 创建Course实例:

     Course course = new Course(...); 
  2. 获取现有Student

     Student student = entityManager.find(Student.class, id_of_student); 
  3. 将关系连接如下:

     course.getStudents.add(student); student.getCourse().add(course); 
  4. 实际上你应该调用entityManager.persist()来保存一个新实体。 但是在这种情况下,由于student不是新的实体实例而无法工作,而persist()将不会保存现有的实体实例。 所以你可以使用entityManager.merge()即使它在语义上不正确(因为merge应该在分离的实体上使用):

     entityManager.merge(course); 

为了使其工作,您应该在事务中调用所有实体管理器方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM