JPA @ManyToOne avec CascadeType.ALL

Je pense avoir manqué de comprendre la signification de la cascade dans le contexte de la relation @ManyToOne .

L’affaire:

 public class User { @OneToMany(fetch = FetchType.EAGER) protected Set
userAddresses; } public class Address { @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) protected User addressOwner; }

Quelle est la signification de la cascade = CascadeType.ALL ? Par exemple, si je supprime une certaine adresse de la firebase database, comment le fait d’avoir ajouté la cascade = CascadeType.ALL affecte-t-il mes données (l’utilisateur, je suppose)?

    La signification de CascadeType.ALL est que la persistance propagera (en cascade) toutes les opérations PERSIST, REMOVE, REFRESH, MERGE, DETACH ( PERSIST, REMOVE, REFRESH, MERGE, DETACH ) vers les entités PERSIST, REMOVE, REFRESH, MERGE, DETACH .

    Dans votre cas, il semble que ce soit une mauvaise idée, car la suppression d’une Address entraînerait la suppression de l’ User associé. Un utilisateur pouvant avoir plusieurs adresses, les autres adresses deviendraient orphelines. Toutefois, le cas inverse (annotation de l’ User ) aurait du sens – si une adresse appartient à un seul utilisateur, il est conseillé de propager la suppression de toutes les adresses appartenant à un utilisateur si cet utilisateur est supprimé.

    BTW: vous pouvez append un mappedBy="addressOwner" à votre User pour signaler au fournisseur de persistance que la colonne de jointure doit se trouver dans la table ADDRESS.

    Voir ici pour un exemple des documents OpenJPA. CascadeType.ALL signifie qu’il fera toutes les actions.

    Citation:

    CascadeType.PERSIST: lors de la persistance d’une entité, persistez également les entités détenues dans ce champ. Nous suggérons une application libérale de cette règle en cascade, car si EntityManager trouve un champ faisant référence à une nouvelle entité pendant le vidage et que le champ n’utilise pas CascadeType.PERSIST, il s’agit d’une erreur.

    CascadeType.REMOVE: lors de la suppression d’une entité, supprimez également les entités contenues dans ce champ.

    CascadeType.REFRESH: lors de l’actualisation d’une entité, actualisez également les entités contenues dans ce champ.

    CascadeType.MERGE: lors de la fusion de l’état de l’entité, fusionnez également les entités détenues dans ce champ.

    Sebastian

    De la spécification EJB3.0 :

    L’utilisation de l’élément d’annotation en cascade peut être utilisée pour propager l’effet d’une opération sur des entités associées. La fonctionnalité en cascade est généralement utilisée dans les relations parent-enfant.

    Si X est une entité gérée, l’opération de suppression entraîne sa suppression. L’opération de suppression est mise en cascade sur les entités référencées par X, si les relations entre X et ces autres entités sont annotées avec la cascade = REMOVE ou cascade = ALL élément d’annotation.

    En CascadeType.All , les relations d’entité définies avec CascadeType.All garantissent que tous les événements de persistance, tels que la persistance, l’actualisation, la fusion et la suppression, survenant sur le parent, seront transmis à l’enfant. La définition d’autres options CascadeType fournit au développeur un niveau de contrôle plus granulaire sur la manière dont l’association d’entités gère la persistance.

    Par exemple, si j’avais un object Book qui contenait une liste de pages et que j’ajoutais un object page dans cette liste. Si l’annotation @OneToMany définissant l’association entre Book et Page est marquée comme CascadeType.All , la persistance du Book entraînerait la persistance de la page dans la firebase database.

    Comme je l’ai expliqué dans cet article et dans mon livre, Persistance Java hautes performances , vous ne devez jamais utiliser CascadeType.ALL sur @ManyToOne car les transitions d’état d’entité doivent se propager des entités @ManyToOne à celles des enfants.

    Le côté @ManyToOne est toujours l’association Child car il doit mapper le FK sous-jacent.

    Par conséquent, déplacez CascadeType.ALL de l’association @ManyToOne vers @OneToMany qui doit utiliser l’atsortingbut mappedBy car il s’agit du mappage un-à-plusieurs le plus efficace . `

    Dans JPA 2.0, si vous souhaitez supprimer une adresse si vous l’avez supprimée d’une entité utilisateur, vous pouvez append orphanRemoval=true (au lieu de CascadeType.REMOVE ) à votre @OneToMany .

    Plus d’explications entre orphanRemoval=true et CascadeType.REMOVE est ici .