2009-07-21 13 views
0

J'ai une relation many-to-many définie entre deux entités utilisant une table d'association et cascade = "save-update".NHibernate exécution de requête UPDATE supplémentaire

Entity1 contient une liste d'Entity2 et, inversement, Entity2 contient une liste d'Entity1. Le SQL de cette worflow en sortie semble ok ...

  1. Créer un objet Entité1 et Entity2
  2. Ajouter à la liste des Entity2 sur Entité1
  3. Appel session.Save sur Entité1

-> Des instructions d'insertion sont exécutées pour les deux entités, puis un enregistrement inséré dans la table d'association les reliant entre elles.

Cependant, si je premier appel session.Save sur Entity2, ajoutez à la liste, puis appelez session.Save sur Entité1 il y a une piste de déclaration supplémentaire UPDATE qui définit toutes les valeurs de Entité2 exactement la même chose que a été inséré au début.

Bien que ne causant aucun problème, il s'agit d'une requête supplémentaire pour réduire les performances. J'ai joué avec l'attribut inverse, mais cela n'élimine pas l'instruction de mise à jour supplémentaire. Actuellement, les deux côtés ont inverse = "false" car je veux que la table d'association soit mise à jour, quelle que soit l'entité enregistrée.

Des idées?

Répondre

0

Merci pour la réponse, mais je crois que j'ai trouvé le problème. J'ai eu une classe de référentiel pour chaque type d'entité qui a implémenté les opérations CRUD. Chaque opération CRUD a démarré sa propre session/transaction, appelée Save/Update/etc, puis a fermé la transaction/session.

Si j'appelle la session.Sauvegardez pour Entity2 puis session.Sauvegardez pour Entity1 (qui contient la liste d'Entity2) NH semble savoir qu'il a déjà persisté Entity2 dans la session et n'essaie donc pas de mettre à jour l'enregistrement . D'autre part, si j'appelle session.Sauvegarde pour Entity2 puis session.Sauvegarde pour Entity1 dans une session/transaction séparée, il veut mettre à jour Entity2 à nouveau. Je suis nouveau sur NH, donc je ne sais pas comment il surveille quels objets nécessitent une mise à jour, mais il doit être réinitialisé entre les sessions.

Kinda rend mes jolis dépôts DDD un peu moins utiles! Peut-être que les dépôts devraient utiliser une session singleton ou quelque chose de similaire pour éviter ce problème?

Merci, John

+0

rappelez-vous qu'une session n'est pas threadsafe.Je pense que la plupart des gens utilisent 'Session-per-request' dans aspnet ou 'session-per-thread' dans les applications –

+0

Oui, en regardant d'autres exemples sur le web je devrais probablement implémenter une construction 'unité de travail' pour gérer la session peut être instancié à l'ouverture d'un formulaire (application client riche dans mon cas) et fermé (disposition de la session) lorsque le formulaire est éliminé. – John

0

De la docs: inverse (optionnel - par défaut à false): Si activé, Hibernate n'essaiera pas d'insérer ou de mettre à jour les propriétés définies par cette jointure.

Ma suggestion: Dans certains cas, afin d'éviter des mises à jour supplémentaires avec 2 voies relie les deux collections peut être mis à jour:

Contact c; 
Address a;  
c.Addresses.Add(a); 
a.Contacts.Add(c); 

Vous obtenez probablement la déclaration de mise à jour supplémentaire, car les deux parties ont inverse = false et la liste de relations de la première entité a été sauvegardée vide. NH ne fait que ce dont elle a besoin pour mettre à jour toutes ses relations.

Questions connexes