【问题标题】:Why is NHibernate performing an INSERT instead of an update?为什么 NHibernate 执行 INSERT 而不是更新?
【发布时间】:2010-07-06 22:52:15
【问题描述】:

我有以下映射:

<!-- WidgetConfiguration -->
<class name="MyProject.WidgetConfiguration, MyProject" table="WidgetConfigurations">
  <id name="Id" column="Id" type="Int64">
    <generator class="native" />
  </id>

  <property name="Name" column="ConfigurationName" />

  <map name="Widgets" table="WidgetConfigurationPositions" cascade="all" lazy="false" fetch="select" inverse="true">
    <key column="WidgetConfigurationId" />
    <index column="TargetId" type="string" />
    <one-to-many class="MyProject.WidgetPlacement" />
  </map>
</class>
<!-- End WidgetConfiguration -->

<class name="MyProject.WidgetPlacement, MyProject" table="WidgetConfigurationPositions">
  <id name="Id" column="Id" type="Int64">
    <generator class="native" />
  </id>

  <many-to-one name="Widget" class="MyProject.Widget, MyProject" column="WidgetId" lazy="false" />
  <property name="Target" column="TargetId" not-null="true" />

  <map name="Options" table="PlacedWidgetOptions" cascade="all" lazy="false" fetch="select">
    <key column="WidgetConfigurationPositionId"/>
    <index column="OptionName" type="string" />
    <element column="OptionValue" type="string" />
  </map>
</class>

而且,我有以下代码:

public override void Update(WidgetConfiguration obj)
{
 using (var session = GetSession())
 {
  var tx = session.BeginTransaction();
  session.Update(obj);
  tx.Commit();

  //session.Evict(obj);
 }
}

我可以保存一个 WidgetConfiguration 只是花花公子,但试图更新一个 WidgetConfiguration,NHibernate 实际上执行插入!这是来自我的 NHibernate Profiler 的会话。

begin transaction with isolation level: Unspecified

INSERT INTO WidgetConfigurations
           (ConfigurationName)
VALUES     ('dashboard' /* @p0 */)
select SCOPE_IDENTITY()

INSERT INTO WidgetConfigurationPositions
           (WidgetId,
            TargetId)
VALUES     (1 /* @p0 */,
            'row1-column1' /* @p1 */)
select SCOPE_IDENTITY()

UPDATE WidgetConfigurationPositions
SET    WidgetId = 1 /* @p0 */,
       TargetId = 'row1-column2' /* @p1 */
WHERE  Id = 356 /* @p2 */

commit transaction

知道为什么会发生这种情况,而 Google 也不是很有帮助。有人有什么想法吗?

【问题讨论】:

  • 如何获得这个 WidgetConfiguration 实例?您是通过 session.Get()、session.Load() 还是其他查询从数据库中获取它?
  • 毛里科,我通过查询得到它。 var query = session.CreateQuery("FROM WidgetConfigurations wc INNER JOIN FETCH...");返回查询.UniqueResult();。我应该怎么做?
  • 没关系,我只是在检查,以防万一......
  • 能把WidgetConfigurations表的schema贴出来(CREATE TABLE的形式)吗?
  • 进入你的Update方法后WidgetConfigurationg的ID是多少?

标签: c# asp.net-mvc nhibernate


【解决方案1】:

尝试设置未保存值属性:

<id name="Id" column="Id" type="Int64" unsaved-value="0">
    <generator class="native" />
</id>

ID 列的类型是什么?如果长?那么 unsaved-value 应该是null。您不需要设置它,但这是我会尝试的第一件事。

【讨论】:

    【解决方案2】:

    你还记得重写你的 Equals() 和 GetHashCode() 吗?由于您要分离然后重新连接,因此这些方法将发挥作用。

    我建议选择 NHibernate In Action 并阅读有关持久性生命周期的信息 :)

    【讨论】:

      【解决方案3】:

      我的猜测是您的问题是由在一个 NH 会话中检索对象并在另一个会话中更新它引起的。

      要么在整个请求过程中保持 NH 会话打开,要么尝试将(Lock() ?)对象附加到更新的 NH 会话。

      【讨论】:

      猜你喜欢
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多