2010-10-07 14 views
0

J'ai une classe, BillMedicine, qui est une table plusieurs-à-plusieurs pour Bill et Medicine. Le fichier de mappage BillMedicine est:Modification d'une partie d'un ID composite

<class name="BillMedicine" table="Bill_Medicine"> 
    <composite-id> 
     <key-many-to-one name="Bill" class="Bill" column="BillID" /> 
     <key-many-to-one name="Medicine" class="Medicine" column="MedicineID" /> 
    </composite-id> 
    <version name="LastModifiedOn" column="LastModifiedOn" type="DateTime" 
      access="field.pascalcase-underscore" /> 
    <property name="Quantity" column="QuantityPurchased" /> 
</class> 

Lorsque je crée une nouvelle BillMedicine et mettre à jour la quantité mon test unitaire réussit. Toutefois, si je décommentez la ligne qui met à jour la médecine, je suis arrivé à l'exception NHibernate.StaleObjectStateException: Row was updated or deleted by another transaction

BillMedicineRepository target = new BillMedicineRepository(); 
BillMedicine billMedicine = 
    new BillMedicine { Bill = _bill, Medicine = _medicine1, Quantity = 1 }; 
target.AddBillMedicine(billMedicine); 

//billMedicine.Medicine = _medicine2; 
billMedicine.Quantity = 2; 
target.UpdateBillMedicine(billMedicine); // Exception if I update the medicine 

J'ai vérifié le SQL montré par NHibernate et ce ne sont pas la mise à jour de la médecine

UPDATE Bill_Medicine SET LastModifiedOn = @p0, QuantityPurchased = @p1 
WHERE BillID = @p2 AND MedicineID = @p3 AND LastModifiedOn = @p4; 

Edit:

Mes Questions:
1- Pourquoi mettre à jour la quantité qui fonctionne mais que la mise à jour du médicament est exception de jet?
2- Est-il possible de mettre à jour Nhibernate la propriété du médicament? Si oui, comment? Si non, quelqu'un peut-il suggérer une solution?

+0

Notez que le qurey généré par NHibernate pour UpdateBillMedicine ne met pas à jour le MedicineID, pourquoi? –

Répondre

3

NHibernate ne permet pas de changer la clé primaire.

solutions de contournement possibles:

  • Créer une nouvelle instance avec le nouveau médicament et supprimer l'ancien
  • Utilisez un HQL update pour changer la médecine. Gardez à l'esprit que l'état en mémoire ne correspondra pas à la base de données, à moins que vous ne chargiez l'instance et que vous ne la rechargiez à nouveau.
+0

Comment puis-je obtenir l'ancien ID de médicament? Disons que j'ai déjà changé la propriété de la médecine, puis-je avoir le vieux médecin? –

+0

Juste le stocker dans une variable ....... –

0

Je pense que vous devriez créer un autre objet, parce que j'ai un deja-vu ici. Vous essayez de

  1. créer un objet avec la touche B1 M1
  2. enregistrez-le
  3. en gardant le même objet et même référence , en changeant la clé de B1 M2
  4. mise à jour du nouvel objet (avec une ancienne référence )

Je vous recommande soit flushing your session entre la sauvegarde et la mise à jour ou using a transaction pour chacune des opérations (rinçage devrait être suffisant cependant, je recommande la transaction uniquement parce que c'est une bonne pratique :)). J'ai le sentiment que vous essayez de mettre à jour un objet qui n'a pas encore été inséré

+0

Dans AddBillMedicine et UpdateBillMedicine, je sauvegarde/met à jour en utilisant une nouvelle transaction. J'ai également essayé d'ajouter la session. Flush mais en vain. Le point est si je mets à jour la quantité seulement la mise à jour réussit cependant si je mets à jour le médicament la mise à jour échoue. –

+0

Aussi, je ne suis pas en train de mettre à jour un nouvel obejct, je suis en train de mettre à jour l'objet que je viens d'enregistrer. –

+0

sh_kamath: c'est un nouvel objet en ce sens que sa clé est différente. Dans une base de données comme celle-ci, B1M1 et B1M2 doivent être différents objets – samy