【问题标题】:NHibernate and Integer Columns as VersionNHibernate 和整数列作为版本
【发布时间】:2019-06-07 10:40:35
【问题描述】:

我正在尝试使用 NHibernate *hbm.xml 映射文件创建一个 DB 表,该文件将具有一个用于并发检查的版本控制列。版本控制列应该是一个可为空的整数。

虽然数据库创建得很好,但使用映射文件作为参考,会发生以下情况: * 插入第一条记录,其值为 NULL 作为版本 * 先前插入的记录更新失败,出现“Stale Data”异常

换句话说,无论我做什么,Version 列始终为 NULL。 我对使用 NHibernate 的并发控制有点陌生,所以我不太明白我做错了什么..

如果我使用时间戳作为版本,一切正常。但是,我的要求是使用整数。这就是我的问题。

这是我的映射文件:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" auto-import="false" assembly="New1.Backend" namespace="New1.BO">
    <class name="Natrio" table="`Natrios`" schema="`dbo`">
        <cache usage="read-write" />
        <id name="Id" column="`Id`" type="System.Int32">
            <generator class="NHibernate.Id.Enhanced.TableGenerator">
                <param name="increment_size">200</param>
                <param name="segment_value">Natrios</param>
                <param name="optimizer">pooled-lo</param>
            </generator>
        </id>
        <version name="Version" column="`Version`" type="System.Nullable`1[[System.Int32, mscorlib]], mscorlib" generated="always" unsaved-value="0">
            <column name="`Version`" not-null="false" sql-type="int" />
        </version>
        <property name="Attribute" column="`Attribute`" type="String" not-null="false" length="100" />
    </class>
</hibernate-mapping>

任何想法和/或建议将不胜感激!

【问题讨论】:

    标签: nhibernate concurrency nhibernate-mapping database-versioning


    【解决方案1】:

    为什么需要可为空的版本列?无论如何,我相信问题是由您的映射中的unsaved-value="0" 引起的。由于可空列的默认值为null - NHibernate 认为该值已经生成,因此从未分配过。您需要将其设置为 null - unsaved-value="null" 以使其与可为空的列一起使用。unsaved-value="0" 对于不可为空的类型有意义。但最好完全省略此属性并让 NHibernate 为 s

    generated 属性的另一个问题。这是关于数据库生成的——所以always 表示这个值是由数据库自动生成的。您应该删除它或将其指定为generated="never"

    我相信以下映射应该适合您:

    <version name="Version">
        <column name="`Version`" not-null="false" sql-type="int" />
    </version>
    

    【讨论】:

    • 嗯,可空版本列与系统要求有关。不过,我应用了您的建议,但没有任何变化...... Version 列仍保存为 NULL,当我更新记录时,我面临 Stale Data 异常。
    • 仅供参考,如果我使用以下映射,则会再次发生完全相同的行为:xml &lt;version name="Version" column="`Version`" type="System.Int32" generated="always" unsaved-value="null"&gt; &lt;column name="`VersionTimestamp`" not-null="false" sql-type="int" /&gt; &lt;/version&gt; 请注意普通整数(而不是 Nullable),我只是不知道它的问题是什么。跨度>
    • 好吧。不知道为什么它不适用于可空类型。但是您最后的映射不正确 - 对于 int 它应该是 0 而不是 null
    • unsaved-value="0" 相同。 NHibernate 文档声明 Integer 是 Version 列的 默认 类型,但是它绝对没有示例!现在我使用一个不可为空的System.Int32 和一个0 未保存的值,没有任何改变。我只是不知道它需要我什么。
    • 其实generated="always"表示这个值是DB生成的。您应该省略此属性或将其指定为 generated="never"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2011-04-07
    相关资源
    最近更新 更多