簡體   English   中英

在 Spring jpa 使用@ManyToMany 關系,為什么要用@Embeddable 創建一個新的 class?

[英]in Spring jpa using the @ManyToMany relationship, why create a new class with @Embeddable?

根據 Spring JPA 文檔,在多對多關系(學生 - 課程)中我們必須創建一個新表(student_course)

class 學生 ---> class 學生課程 <--- class 課程

根據文檔,如果我們想向表 (student_course) 添加一個新屬性,我們必須創建一個新的 class,它將包含學生 class 和課程 class 的復合鍵

@Embeddable
class CourseStudentKey implements Serializable {


@Column(name="student_id")
Long studentId;


@Column(name = "course_id")
Long courseId;
}

_ 然后給 Student_Course class 我們分配包含復合鍵的 CourseStudentKey 類型的 id:

@Entity
class StudentCourse {

@EmbeddedId
CourseRatingKey id;

@ManyToOne
@MapsId("studentId")
@JoinColumn(name = "student_id")
Student student;

@ManyToOne
@MapsId("courseId")
@JoinColumn(name = "course_id")
Course course;
}

我的問題是:僅創建 StudentCourse class 並將 @ManyToOne 映射到 Student class 和 Course class 有什么區別??...這樣我們還可以向 StudentCourse class 添加屬性

_克拉斯學生

@Entity
class Student {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private idStudent;

@JsonIgnore
@OneToMany(mappedBy = "student")
List<StudentCourse> studentCourses = new ArrayList<>();

_課程

@Entity
class Course{

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private idCourse;

@JsonIgnore
@OneToMany(mappedBy = "course")
List<StudentCourse> studentCourses = new ArrayList<>();
}

_Clase學生課程

@Entity 
class StudentCourse {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private idStudentCourse;

@ManyToOne
@JoinColumn(name = "student_id")
Student student;

@ManyToOne
@JoinColumn(name = "course_id")
Course course;
}

您發布的示例中的唯一區別是,在 Embeddable 的情況下, student_id course_id Embeddable是一個復合鍵,因此每個student_id course_id組合只允許一行。 而在第二個示例中,您使用了生成的主鍵,確保每個student_id course_id組合有多行。 如果學生第一次未通過課程並再次嘗試,這將特別有用。 然后,您可以將attemped_on, is_completed等參數添加到 student_course 實體

您的示例顯示了密鑰的差異,正如 Chetan 的回答所述,這會影響表中使用的密鑰。 這里的選擇不一定是使用單獨的類/嵌入式 class,而是使用單個生成的標識符與使用實體的復合主鍵。

在您發布的嵌入式示例中,您有一個基於外鍵映射的復合主鍵。 map 這個相同的設置還有很多其他方法,但共同的部分是:

  1. 復合 PK 需要一個 ID class。它不必嵌入您的 class(請參閱 JPA 派生 ID ),但確實需要存在。 這是 JPA 規范的一部分,允許 em.find 操作處理單個 object。
  2. ID 值是不可變的。 根據 JPA 規范,如果沒有刪除/持久化操作,它們就無法更改。 許多提供者甚至不喜歡您嘗試在實體實例中修改它們。 在您的可嵌入示例中,您不能更改引用,而在生成的 id 示例中,您可以。

它還會影響 JPA 要求您在外鍵中使用的內容。 如果您使用復合 ID,則需要該表的外鍵的對該實體 (*ToOne) 的任何引用都需要使用其定義的 ID - 構成該 ID 的所有列。 一些提供商不強制執行此操作,但它會影響實體緩存; 由於實體緩存在它們的 ID 上,使用其他東西作為 FK 的目標可能意味着數據庫命中已經在緩存中的實體。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM