पाठ 11 / 25
Many-to-Many and One-to-One
Map many-to-many with a join table or an explicit entity, and one-to-one relationships.
Join tables and shared keys
@ManyToMany maps a relationship through a join table (@JoinTable with joinColumns and inverseJoinColumns): students and courses, products and tags. Use a Set rather than a List for many-to-many collections, because Hibernate handles List bags inefficiently on removal (deleting and reinserting all rows). As soon as the relationship needs its own attributes (enrolment date, grade, quantity), replace @ManyToMany with an explicit entity for the association (Enrolment) and two @ManyToOnes; this is also easier to query and evolve, and many teams prefer it from the start. @OneToOne maps one-to-one relationships, such as a user and their profile. The most efficient mapping shares the primary key with @MapsId, so the child's ID equals the parent's; a separate foreign key column also works. Remember that @OneToOne and @ManyToOne default to eager fetching; mark them LAZY. A bidirectional @OneToOne inverse side often cannot be lazy without bytecode enhancement, a common performance surprise.
Tags as many-to-many, enrolment as an explicit entity, profile with @MapsId
Choose the explicit entity when the link has data.
@Entity
public class Article {
@Id @GeneratedValue private Long id;
@ManyToMany
@JoinTable(name = "article_tags",
joinColumns = @JoinColumn(name = "article_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
private Set<Tag> tags = new HashSet<>(); // Set, not List
}
@Entity
public class CourseEnrolment { // association with attributes
@Id @GeneratedValue private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false) private Student student;
@ManyToOne(fetch = FetchType.LAZY, optional = false) private Course course;
private LocalDate enrolledOn;
private String grade;
}
@Entity
public class UserProfile {
@Id private Long id; // same value as the user's id
@OneToOne(fetch = FetchType.LAZY)
@MapsId
private AppUser user;
private String bio;
}A guest list versus a ticket stub
A plain many-to-many is a guest list linking guests to parties. Once you need to record which seat each guest had and what they paid, you need a ticket stub for each pairing: an entity of its own.
त्वरित जाँच: A student-course relationship needs to store the grade. How should it be mapped?
- @ManyToMany with a List
- An explicit association entity (e.g. Enrolment) with two @ManyToOne relationships
- A comma-separated column
- @OneToOne
Answer
An explicit association entity (e.g. Enrolment) with two @ManyToOne relationships — Attributes on the link require an entity for the association.