[ Hibernate 3.5 ] – Suppression des orphelins

Voici un petit point sur la suppression des orphelins avec Hibernate 3.5.1 et JPA 1.0.0.Final.

Contexte

J'ai un bean Article qui est associé en @OneToMany à des commentaires.

   import javax.persistence.OneToMany;
   import javax.persistence.CascadeType;
   import org.hibernate.annotations.LazyCollection;
   import org.hibernate.annotations.LazyCollectionOption;
   import org.hibernate.annotations.Sort;
   import org.hibernate.annotations.SortType;
   // ...
   public class Article
       implements Serializable
   {
       // ...
       @OneToMany(mappedBy = "article", cascade = CascadeType.ALL)
       @LazyCollection(LazyCollectionOption.TRUE)
       @Sort(type = SortType.COMPARATOR, comparator = CommentaireComparator.class)
       private SortedSet<Commentaire> commentaires =
           new TreeSet<Commentaire>(new CommentaireComparator());
   }

Objectif

Ce qui m'intéresse ici est la façon dont les objets Commentaire sont supprimés en cascade par Hibernate.

Pour rappel, les deux actions de suppression suivantes sont gérées différemment par hibernate :
1) Je supprime une instance de Article liée à des commentaires.
2) Je supprime une occurrence de commentaire dans l'objet SortedSet rattaché à une instance de Article.

Solution

1) Suppression d'une instance de Article liée à des commentaires.

La suppression d'une instance d'Article supprime les commentaires associés grâce à la balise @OneToMany(mappedBy = "article", cascade = CascadeType.ALL), et notamment le cascade = CascadeType.ALL car celui-ci inclut l'option REMOVE.

2) Suppression d'une occurence de Commentaire dans le SortedSet d'une instance de Article
Cette seconde action n'est pas prise en compte par l'option cascade décrite précédemment. Ici, nous souhaitons, d'après le langage hibernate, supprimer en cascade les orphelins, c'est-à-dire qu'un commentaire qui n'est plus référencé par aucun article sera supprimé automatiquement lors de l'enregistrement de l'article qui le référençait. Dans l'état actuel du code, cette suppression des orphelins n'est pas prise en compte : si je supprime un commentaire de l'article, celui-ci ne sera pas supprimé lors de l'enregistrement de l'article; le prochain rechargement de l'article aura donc pour conséquence la réapparition du commentaire dans la liste des commentaires de mon article. Auparavant, nous réglions ce problème en ajoutant @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) sur l'association.
Cependant, depuis la version 3.5 d'hibernate, cette option est marquée deprecated. Il faut en effet remplacer la ligne par un attribut supplémentaire dans l'annotation JPA : orphanRemoval=true.

Il faut donc mettre à jour le code précédent pour gérer de manière transparente la suppression des commentaires dans les deux cas décrits :

   import javax.persistence.OneToMany;
   import javax.persistence.CascadeType;
   import org.hibernate.annotations.LazyCollection;
   import org.hibernate.annotations.LazyCollectionOption;
   import org.hibernate.annotations.Sort;
   import org.hibernate.annotations.SortType;
   // ...
   public class Article
       implements Serializable
   {
       // ...
       @OneToMany(mappedBy = "article", cascade = CascadeType.ALL, orphanRemoval = true)
       @LazyCollection(LazyCollectionOption.TRUE)
       @Sort(type = SortType.COMPARATOR, comparator = CommentaireComparator.class)
       private SortedSet<Commentaire> commentaires =
           new TreeSet<Commentaire>(new CommentaireComparator());
   }

NB : Le principe est le même sur l'annotation @OneToOne.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.