更改复合ID的一部分

时间:2010-10-07 21:15:05

标签: nhibernate many-to-many

我有一个班级,BillMedicine,这是比尔和医学的多对多表。 BillMedicine映射文件是:

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

当我创建一个新的BillMedicine并更新数量时,我的单元测试成功。但是,如果我取消注释更新药物的行,我得到例外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

我已经检查了NHibernate显示的SQL,但它没有更新药物

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

修改

我的问题:
1-为什么只更新数量是有效的,但是更新药物会引起异常? 2-是否可以使Nhibernate更新药物属性?如果有,怎么样?如果不是,有人可以提出解决方法吗?

2 个答案:

答案 0 :(得分:3)

NHibernate不允许更改主键。

可能的解决方法:

  • 使用新药创建新实例并删除旧实例
  • 使用HQL update更改“药物”。请记住,除非Evict实例并再次加载,否则内存状态将与数据库不匹配。

答案 1 :(得分:0)

我认为你应该创造另一个对象,因为我在这里有一个似曾相识的东西。你试图

  1. 使用键B1 M1
  2. 创建一个对象
  3. 保存
  4. 保持相同的对象和相同 参考,将密钥更改为B1 M2
  5. 更新新对象(使用旧对象) 参考)
  6. 我建议在保存和更新之间使用flushing your session,或者为每个操作建议using a transaction(虽然刷新应该足够了,但我推荐这项交易只是因为这是一个很好的做法:) )。我感觉您正在尝试更新尚未插入的对象