代码之家  ›  专栏  ›  技术社区  ›  sh_kamalh

更改复合ID的一部分

  •  0
  • sh_kamalh  · 技术社区  · 14 年前

    我有一个班,bill medicine,这是许多对许多表的bill和medicine。 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 回复  |  直到 14 年前
        1
  •  3
  •   Diego Mijelshon    14 年前

    NHibernate不允许更改主键。

    可能的解决方法:

    • 使用新药物创建新实例并删除旧实例
    • 使用一个 HQL update 换药。请记住,除非您 Evict 实例并再次加载。
        2
  •  0
  •   samy    14 年前

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

    1. 使用键b1 m1创建对象
    2. 保存它
    3. 保持相同的对象和相同的 参考,将键更改为b1 m2
    4. 更新新对象(使用旧对象 参考文献)

    我也推荐你 flushing your session 在保存和更新之间,或 using a transaction 对于每一个操作(刷新应该足够了,不过,我建议只使用事务,因为这是一个好的实践:)。我觉得你正在更新一个尚未插入的对象