View on GitHub

lp4-2019

One-to-many et many-to-many : problèmes classiques et bonnes pratiques

Suppression en Cascade

Le but est de supprimer les lignes d’une table qui sont référencés dans une autre table, sous forme de FK. Par défaut, cela lève une contrainte d’intégrité. Pour illustrer on va utiliser ce repo qui contient :

https://github.com/jtobelem-simplon/hibernate-many-to-many

one-to-many : trois options

On a les tables suivantes :

titres
img

categories
img

On a les entités suivantes :

Titre.java

public class Titre {

  ...
  // Pour supprimer une categorie associée à des titres (oneToMany), trois options :
   // **** Option1 - @OnDelete(action = OnDeleteAction.CASCADE) : utilise le mecanisme db : https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/annotations/OnDeleteAction.html
   // **** Option2 - @OneToMany(mappedBy = "categorie", cascade = CascadeType.REMOVE) dans la classe categorie
   // **** Option3 - @OneToMany(mappedBy = "categorie", orphanRemoval = true) dans la classe categorie
   @ManyToOne
   @OnDelete(action = OnDeleteAction.CASCADE)
   @JoinColumn(name = "categorie", referencedColumnName = "id")
   private Categorie categorie;
}

Categorie.java

public class Categorie {

  ...

  // Optionnellement, on peut ajouter l'autre direction de la relation : un lien vers une collection de titres
  // Pour supprimer une categorie associée à des titres (oneToMany), trois options : (voir option 1 dans Titre)
  // **** Option2 - @OneToMany(mappedBy = "categorie", cascade = CascadeType.REMOVE)
  // **** Option3 - @OneToMany(mappedBy = "categorie", orphanRemoval = true)
  // difference entre option2 et 3 : https://stackoverflow.com/a/18813411/10364570
//    @OneToMany(mappedBy = "categorie")
//    private Set<Titre> titres = new HashSet<>();
}

many-to-many : deux options

En fait pas si problématique, il suffit de supprimer en cascade des lignes dans la table intermédiaire.

On a les tables suivantes :

titres
img

auteurs
img

auteur/titre
img

On a les entités suivantes :

Titre.java

public class Titre {

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

    private String nom;

    // Pour supprimer des titres associés à des auteurs (manyToMany), deux options à placer dans la classe qu'on veut pouvoir supprimer :
    // **** Option1 - @OnDelete(action = OnDeleteAction.CASCADE) : utilise le mecanisme db : https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/annotations/OnDeleteAction.html
    // **** Option2 - @ManyToMany(mappedBy="titres", cascade = CascadeType.REMOVE)
    // ?? https://thoughts-on-java.org/hibernate-tips-the-best-way-to-remove-entities-from-a-many-to-many-association/
    @ManyToMany(mappedBy = "titres")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Set<Auteur> auteurs = new HashSet<>();
}

@author Josselin Tobelem