开发者

Changing part of a composite-id

开发者 https://www.devze.com 2023-01-18 23:27 出处:网络
I have a class, BillMedicine, which is many-to-many table for Bill and Medicine. The BillMedicine mapping file is:

I have a class, BillMedicine, which is many-to-many table for Bill and Medicine. The BillMedicine mapping file is:

<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>

When I create a new BillMedicine and update the quantity my unit test succeeds. However if I uncomment the line that updates the medicine, I got the 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

I have checked the SQL shown by NHibernate and it is not updating the medicine

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

Edit:

My Que开发者_如何学Gostions:

1- Why updating the quantity only is working but updating the medicine is throwing exception?

2- Is it possible to make Nhibernate update the medicine property? If yes, how? If no, can someone suggest a workaround?


NHibernate does not allow changing the primary key.

Possible workarounds:

  • Create a new instance with the new medicine and delete the old one
  • Use an HQL update to change the Medicine. Keep in mind that the in-memory state won't match the DB unless you Evict the instance and load it again.


I think you should create another object, because i have a deja-vu here. Your trying to

  1. create an object with the key B1 M1
  2. save it
  3. keeping the same object and same reference, changing the key to B1 M2
  4. updating the new object (with an old reference)

I'd recommend either flushing your session between the save and the update, or using a transaction for each of the operations (flushing should be enough though, i recommend the transaction only because it's a good practice :) ). I have the feeling you're trying to update an object that hasn't been inserted yet

0

精彩评论

暂无评论...
验证码 换一张
取 消