我有一个带有指定ID的实体“Group”,它被添加到聚合中以便保留它。这会导致问题,因为NHibernate无法判断它是新的还是现有的。为解决此问题,我更改了映射以使Group实体在sql时间戳版本列上使用乐观锁定。这引起了一个新问题。 Group有一包子对象。因此,当NHibernate将新组刷新到数据库时,它首先在Groups表中创建Group记录,然后插入每个子对象,然后更新Group记录以更新时间戳值。但是,当映射为dynamic-update =“true”和optimistic-lock =“version”时,为完成更新而生成的sql无效。
以下是映射:
<class xmlns="urn:nhibernate-mapping-2.2" dynamic-update="true" mutable="true" optimistic-lock="version" name="Group" table="Groups">
<id name="GroupNumber" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="GroupNumber" length="5" />
<generator class="assigned" />
</id>
<version generated="always" name="Timestamp" type="BinaryBlob" unsaved-value="null">
<column name="TS" not-null="false" sql-type="timestamp" />
</version>
<property name="UID" update="false" type="System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="GroupUID" unique="true" />
</property>
<property name="Description" type="AnsiString">
<column name="GroupDescription" length="25" not-null="true" />
</property>
<bag access="field.camelcase-underscore" cascade="all" inverse="true" lazy="true" name="Assignments" mutable="true" order-by="GroupAssignAssignment">
<key foreign-key="fk_Group_Assignments">
<column name="GroupNumber" />
</key>
<one-to-many class="Assignment" />
</bag>
<many-to-one class="Aggregate" name="Aggregate">
<column name="GroupParentID" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
当映射包括动态更新和乐观锁时,生成的sql是:
UPDATE groups SET WHERE GroupNumber = 11111 AND TS=0x00000007877
由于没有SET语句,这显然无效。如果我删除动态更新部分,则在此更新语句期间所有内容都会更新。这使得语句有效,但不必要。
以前有人见过这个问题吗?我错过了什么吗?
谢谢,史蒂夫
答案 0 :(得分:1)
我有完全相同的问题,在我终于开始工作之前,我花了一个时间来绊倒文档。 您需要将bag元素的optimistic-lock属性设置为false。当没有更新可更新属性时,这将阻止NH标记父更新。 我希望这适合你。
答案 1 :(得分:0)
尝试在id元素中设置unsaved-value属性;这应该允许NHibernate区分新记录和现有记录并回避时间戳问题。
<id name="GroupNumber" unsaved-value="" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
The documentation让我相信这应该默认为空字符串,但值得一试。