C'est une question très courante, donc cette réponse est basée sur cet article que j'ai écrit sur mon blog.
Un à plusieurs
La relation de table un à plusieurs se présente comme suit:

Dans un système de base de données relationnelle, une relation de table un-à-plusieurs lie deux tables sur la base d'un Foreign Key colonne de l'enfant qui fait référence à la ligne Primary Keyde la table parent.
Dans le diagramme de tableau ci-dessus, la post_idcolonne du post_commenttableau a une Foreign Keyrelation avec la colonne d' postID de table Primary Key:
ALTER TABLE
post_comment
ADD CONSTRAINT
fk_post_comment_post_id
FOREIGN KEY (post_id) REFERENCES post
Annotation @ManyToOne
La meilleure façon de mapper la relation de table un à plusieurs consiste à utiliser @ManyToOne annotation.
Dans notre cas, l'entité enfant PostCommentmappe la post_idcolonne de clé étrangère à l'aide de l' @ManyToOneannotation:
@Entity(name = "PostComment")
@Table(name = "post_comment")
public class PostComment {
@Id
@GeneratedValue
private Long id;
private String review;
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
}
Utilisation du JPA @OneToMany annotation
Ce @OneToManyn'est pas parce que vous avez la possibilité d'utiliser l' annotation que cela doit être l'option par défaut pour chaque un-à-plusieurs relation de base données . Le problème avec les collections est que nous ne pouvons les utiliser que lorsque le nombre d'enregistrements enfants est plutôt limité.
La meilleure façon de mapper une @OneToManyassociation est de s'appuyer sur le @ManyToOnecôté pour propager tous les changements d'état d'entité:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
//Constructors, getters and setters removed for brevity
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
}
L'entité parente,, Postprésente deux méthodes utilitaires (par exemple addCommentet removeComment) qui sont utilisées pour synchroniser les deux côtés de l'association bidirectionnelle. Vous devez toujours fournir ces méthodes chaque fois que vous travaillez avec une association bidirectionnelle car, sinon, vous risquez des problèmes de propagation d'état très subtils .
L' @OneToManyassociation unidirectionnelle est à éviter car elle est moins efficace que l'utilisation @ManyToOneou l' @OneToManyassociation bidirectionnelle .
Pour plus de détails sur la meilleure façon de cartographier la @OneToManyrelation avec JPA et Hibernate, consultez cet article .
Un par un
La relation de table un-à-un se présente comme suit:

Dans un système de base de données relationnelle, une relation de table un-à-un lie deux tables en fonction d'une Primary Keycolonne de l'enfant qui fait également Foreign Keyréférence à la ligne Primary Keyde la table parent.
Par conséquent, nous pouvons dire que la table enfant partage le Primary Keyavec la table parent.
Dans le diagramme ci-dessus, la idcolonne du post_detailstableau a également une Foreign Keyrelation avec la colonne du posttableau id Primary Key:
ALTER TABLE
post_details
ADD CONSTRAINT
fk_post_details_id
FOREIGN KEY (id) REFERENCES post
Utilisation de JPA @OneToOneavec des @MapsIdannotations
La meilleure façon de cartographier une @OneToOnerelation est d'utiliser @MapsId. De cette façon, vous n'avez même pas besoin d'une association bidirectionnelle puisque vous pouvez toujours récupérer l' PostDetailsentité en utilisant l' Postidentifiant d'entité.
Le mappage ressemble à ceci:
[code language = "java"] @Entity (name = "PostDetails") @Table (name = "post_details") classe publique PostDetails {
@Id
private Long id;
@Column(name = "created_on")
private Date createdOn;
@Column(name = "created_by")
private String createdBy;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "id")
private Post post;
public PostDetails() {}
public PostDetails(String createdBy) {
createdOn = new Date();
this.createdBy = createdBy;
}
//Getters and setters omitted for brevity
} [/ code]
De cette façon, la idpropriété sert à la fois de clé primaire et de clé étrangère. Vous remarquerez que la @Idcolonne n'utilise plus d' @GeneratedValueannotation puisque l'identifiant est rempli avec l'identifiant de l' postassociation.
Pour plus de détails sur la meilleure façon de cartographier la @OneToOnerelation avec JPA et Hibernate, consultez cet article .
Plusieurs à plusieurs
La relation de table plusieurs à plusieurs se présente comme suit:

Dans un système de base de données relationnelle, une relation de table plusieurs à plusieurs lie deux tables parentes via une table enfant qui contient deux Foreign Keycolonnes référençant les Primary Keycolonnes des deux tables parentes.
Dans le diagramme de tableau ci-dessus, la post_idcolonne du post_tagtableau a également une Foreign Keyrelation avec la colonne d' postid de table Primary Key:
ALTER TABLE
post_tag
ADD CONSTRAINT
fk_post_tag_post_id
FOREIGN KEY (post_id) REFERENCES post
Et, la tag_idcolonne de la post_tagtable a une Foreign Keyrelation avec la colonne d' tagID de table Primary Key:
ALTER TABLE
post_tag
ADD CONSTRAINT
fk_post_tag_tag_id
FOREIGN KEY (tag_id) REFERENCES tag
Utilisation du @ManyToManymappage JPA
Voici comment mapper la many-to-manyrelation de table avec JPA et Hibernate:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "post_tag",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id")
)
private Set<Tag> tags = new HashSet<>();
//Getters and setters ommitted for brevity
public void addTag(Tag tag) {
tags.add(tag);
tag.getPosts().add(this);
}
public void removeTag(Tag tag) {
tags.remove(tag);
tag.getPosts().remove(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Post)) return false;
return id != null && id.equals(((Post) o).getId());
}
@Override
public int hashCode() {
return 31;
}
}
@Entity(name = "Tag")
@Table(name = "tag")
public class Tag {
@Id
@GeneratedValue
private Long id;
@NaturalId
private String name;
@ManyToMany(mappedBy = "tags")
private Set<Post> posts = new HashSet<>();
//Getters and setters ommitted for brevity
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Tag tag = (Tag) o;
return Objects.equals(name, tag.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
- L'
tagsassociation dans l' Postentité définit uniquement les types PERSISTet MERGEcascade. Comme expliqué dans cet article , la REMOVE transition d'état d'entité n'a aucun sens pour une @ManyToManyassociation JPA car elle pourrait déclencher une suppression de chaîne qui effacerait finalement les deux côtés de l'association.
- Comme expliqué dans cet article , les méthodes de l'utilitaire d'ajout / suppression sont obligatoires si vous utilisez des associations bidirectionnelles afin que vous puissiez vous assurer que les deux côtés de l'association sont synchronisés.
- L'
Postentité utilise l'identificateur d'entité pour l'égalité car elle ne dispose d'aucune clé métier unique. Comme expliqué dans cet article , vous pouvez utiliser l'identificateur d'entité pour l'égalité tant que vous vous assurez qu'il reste cohérent dans toutes les transitions d'état d'entité .
- L'
Tagentité possède une clé métier unique marquée de l' @NaturalIdannotation spécifique à Hibernate . Dans ce cas, la clé métier unique est le meilleur candidat pour les contrôles d'égalité .
- L'
mappedByattribut de l' postsassociation dans l' Tagentité marque que, dans cette relation bidirectionnelle, l' Postentité est propriétaire de l'association. Cela est nécessaire car un seul côté peut posséder une relation et les modifications ne sont propagées à la base de données que de ce côté particulier.
- Il
Setest préférable d'utiliser un Listavec @ManyToManyest moins efficace.
Pour plus de détails sur la meilleure façon de cartographier la @ManyToManyrelation avec JPA et Hibernate, consultez cet article .