Ressources
Affirmation
Si on ne précise pas le
mappedByune table de jointure sera créée, voir par exemple OneToMany relation
On revient brièvement sur l’annotation @mappedBy et son utilité.
The main difference is that bidirectional relationship provides navigational access in both directions, so that you can access the other side without explicit queries. Also it allows you to apply cascading options to both directions. 1
- Via une relation bidirectionnelle nous aurons access au getter et setter des deux côtés de la relation (du parent → l’enfant et de l’enfant → le parent)
- Concernant la gestion du cascading
- Nous pouvons le mettre que d’un seul côté (supprimer un post supprimera tous les commentaires)
- Et/ou de l’autre côté également (supprimer tous les commentaires supprimera le post)
Explications
Nous souhaitons représenter le fait qu’un Post a plusieurs commentaires.
class Post {
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
)
private List<Comment> comments = new ArrayList<>();
}class Comment {
@ManyToOne
@JoinColumn(name = "post_id")
private Post post;
}Conséquence du mappedBy
- L’attribut
mappedByindique que le côté@ManyToOneest responsable de la gestion de la colonne de clé étrangère.- En effet, nous souhaitons que la FK soit bien dans la table
Comment - Donc en valeur du
mappedBynous mettons l’attribut dont nous ne souhaitons pas qu’il contienne la FK
- En effet, nous souhaitons que la FK soit bien dans la table
Conséquence du CascadeType
Ressources
- La collection est utilisée uniquement pour récupérer les entités enfants et pour propager les changements d’état de l’entité parente aux enfants.
- En effet, la suppression d’un
postdoit entraîné la suppressions des commentaires associés - MAIS la suppression d’un
commentne doit pas entraîné la suppression du post
- En effet, la suppression d’un
Terminologie
Ressources
- Le
inverse sideest le côté qui contient l’attributmappedBy(nousPost) - Le
owning sideest le côté de la relation qui onws la clé étrangère (nousComment)
The
mappedByattribute tells that the@ManyToOneside is in charge of managing the Foreign Key column, and the collection is used only to fetch the child entities and to cascade parent entity state changes to children (e.g., removing the parent should also remove the child entities).
Synchroniser les deux côté de la relation
Ressources
Nous avons déjà évoqué le sujet dans la section dédiée [copie defensive](% relref “copie_defensive.md” %).
Même si nous avons défini l’attribut mappedBy et que l’association @ManyToOne du côté enfant gère la colonne de clé étrangère, nous devons toujours synchroniser les deux côtés de l’association bidirectionnelle. Et l’un des meilleurs moyen est d’ajouter cette méthode dans la classe Post.
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}Exemple complémentaire
Par exemple si dans notre classe User nous définissons
@Entity
@Table(name = "T_Users")
public class User {
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Command> commands = new HashSet<>();orphanRemoval = trues’assure que si nous supprimons (en code java) une commande d’un utilisateur, alors la commande sera automatique supprimer en base de données (et pas seulement la colonne Fk passée àNULL)cascade = CascadeType.ALLs’assure que si un utilisateur est supprimé alors toutes ses commandes le seront aussi.
try {
// Créer un nouvel utilisateur
User user = new User("john_doe", "password123", 0);
// Créer des commandes et les associer à l'utilisateur
Command command1 = new Command();
Command command2 = new Command();
// Ajouter les commandes à l'utilisateur
user.addCommand(command1);
user.addCommand(command2);
// Persister l'utilisateur, ce qui persiste également les commandes
entityManager.persist(user);
// Valider la transaction
transaction.commit();
} catch (Exception e) {
...
} finally {
// Fermer l'EntityManager
entityManager.close();
entityManagerFactory.close();
}