簡體   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