2010-08-17 7 views
2

J'ai une relation @ManyToMany entre deux entités. Lorsque j'effectue une mise à jour du côté propriétaire, il apparaît que JPA supprime tous les enregistrements liés de ma base de données et les réinsère. Pour moi, c'est un problème parce que j'ai un déclencheur MySQL qui se déclenche avant qu'un enregistrement ne soit supprimé. Des idées sur la façon de contourner ce problème?Mise à jour de JPA Suppression de plusieurs à plusieurs enregistrements

@Entity 
public class User { 

    @Id 
    @Column(name="username") 
    private String username; 

    ... 

    @ManyToMany 
    @JoinTable(name="groups", joinColumns= 
     @JoinColumn(name="username", referencedColumnName="username"), 
      [email protected](name="groupname", 
        referencedColumnName="type_id")) 
    private List<UserType> types; 

    ... 

} 

@Entity 
public class UserType { 

    @Id 
    @Column(name="type_id") 
    private String id; 

    @ManyToMany(mappedBy="types") 
    private List<User> users; 

    ... 
} 

Répondre

1

Il semble mon problème était que je ne fusionnais pas l'entiè ty.

+1

qu'est-ce que cela signifie? J'ai le même problème. Pouvez-vous poster une solution? – Sarah92

+1

Même problème. Pouvez-vous partager votre solution en détail? –

1

Son probablement associé à ce question. Vous devez vous assurer que vous avez un hashCode défini de manière appropriée une méthode equals dans votre objet mappé afin qu'Eclipselink puisse déterminer l'égalité et ainsi déterminer que les objets existants correspondent aux objets existants dans la base de données. Sinon, il n'a d'autre choix que de recréer les objets enfants à chaque fois. J'ai également lu que ce type de jointure peut uniquement prendre en charge l'ajout et la suppression efficaces d'éléments de liste si vous utilisez une colonne d'index, mais cela sera spécifique à EclipseLink, car les annotations JPA ne semblent pas prendre en charge une telle chose. Je sais qu'il existe une annotation Hibernate équivalente, mais je ne sais pas ce que ce serait dans Eclipselink, si une telle chose existe.

+0

Merci pour la perspicacité. J'ai essayé de remplacer les méthodes equals et hashCode dans ma classe User; Cependant, cela n'empêche pas JPA de supprimer/recréer les enregistrements de ma table de jointure. Peut-être que je ne l'implémente pas correctement ... –

+0

JPA n'utilise pas l'identité de l'objet mais l'identité de la base de données. –

1

Essayez celui-ci:

1) Déclaration de modification:

private List<UserType> types = new Vector<UserType>(); 

2) Ne jamais appeler

user.setTypes(newTypesList) 

3) n'appeler

user.getTypes().add(...); 
user.getTypes().remove(...); 
+1

Pourriez-vous expliquer pourquoi je devrais changer ma déclaration? –

2

Utilisez Set au lieu de List résolu le problème. Mais je ne sais pas pourquoi cela fonctionne.

Une autre solution fournie par Hibernate consiste à diviser l'association @ManyToMany en deux relations bidirectionnelles @[email protected]. Voir Hibernate 5.2 documentation par exemple.

Si une association bidirectionnelle @OneToMany fonctionne mieux lorsque suppression ou la modification de l'ordre des éléments enfants, la @ManyToMany relation ne peut pas bénéficier d'une telle optimisation, car le côté clé étrangère ne contrôle pas. Pour surmonter cette limitation, la table de liens doit être directement exposée et l'association @ManyToMany divisée en deux relations @OneToMany bidirectionnelles.

+0

J'utilisais Collection, changé en Set et ça marche bien. Je meurs d'envie de savoir pourquoi .. – alextsil

Questions connexes