【问题标题】:object references an unsaved transient instance save the transient instance before flushing对象引用未保存的瞬态实例 在刷新之前保存瞬态实例
【发布时间】:2011-07-06 12:22:46
【问题描述】:

我有一个自加入员工实体类,其中包含与其自身相关的 id、name 和 ref 列。我想创建它的新实例并将其保存到数据库。

起初,我创建了一个 Employee 类的实例并将其命名为 manager。然后我用这些值从 Employee 表中获取了一条记录:Id = 1,Name = "A",RefId = null 并将这些值设置为管理器对象。之后我再次创建了一个 Employee 类的实例
并像这样设置它的属性值: emp.Name = "B",emp.Ref = 经理。 最后我通过使用 base.Add(resource) 方法来坚持它。当时 Nhibernate 引发了以下错误: “对象引用未保存的瞬态实例在刷新之前保存瞬态实例”。

这是映射文件内容:

<class name="Employee" table="Employee" schema="dbo" optimistic-lock="none" lazy="true">
    <id name="Id" access="property" column="Id">
        <generator class="identity" />
    </id>
    <property name="Name" type="String" column="Name" length="50" />
    <property name="RefId" type="Int64" column="RefId"  insert="false" update="false"/>
    <many-to-one name="Ref" class="Employee" column="RefId" not-null="false" fetch="select" />
 class>

请帮我解决这个错误。 谢谢

【问题讨论】:

  • 为了清楚起见,你的意思是有一个对象是自引用的,还是说有两个员工对象,它们之间有引用? IE,是否有两条员工记录,它们之间有外键,或者有一条员工记录,外键指向主键。
  • 另外,拥有员工实体的映射文件或代码会很有帮助。
  • 感谢您的建议。我会尽量说清楚。我编辑了我的问题。有两个员工记录,它们之间有外键。

标签: c# nhibernate orm nhibernate-mapping


【解决方案1】:

假设实体 1 是数据库中的现有记录,实体 2 是您尝试创建的引用实体 1 的新记录。

Hibernate 告诉您,您正在保存的新实体(实体 2)引用了实体 1(来自数据库的实体),并且实体 1 有未保存的更改,必须先保存这些更改才能保存实体 2。最简单的做法是先保存实体 1,然后保存实体 2。但是,我认为真正的问题是如何获取 Entity1 的实例。

您说您创建了员工实例,然后将其命名为经理,然后从员工表中获取记录。如果您尝试从表中更新现有记录,为什么不先获取实体,然后再编辑它?你为什么要实例化一个对象?我不确定的另一件事是对象之间的关系是否是双向的。也就是说,实体 1 对实体 2 有一个 FK,并且实体 2 对实体 1 也有一个 FK。如果是这种情况,您需要确保两次分配“Ref”属性。 Entityy1.Ref = Entity2 和 Entity2.Ref = Entity1。

【讨论】:

  • 我不想编辑 Db 中现有记录的 Entity1。但我必须获取它,以便将其分配给 Entity2 的具有 Employee 类型的 RefId 属性。
  • 同时,只有 Entity2 有一个 FK,它引用 Entity1 作为它的管理器,但 Entity1 在它的 refId 属性中有一个空值。我的目标是在表中记录这些:在其 refId 列中具有空值的经理和在其 refId 列中具有 managerId 值的员工。
  • 更简单!如果您只需要创建从 Entity2 到 Entity 1 的引用,那么您甚至不需要获取记录。如果知道Entity1的id值,可以使用Entity2.Ref = Session.Load(idValue)。这将为您连接参考。我现在才注意到一些我应该早点发现的东西。您需要删除 RefId 属性。 是进行引用所需的全部内容。有 RefId 是多余的,可能会给您带来一些问题。
  • 你的权利。拥有两个 RefId 和 属性让我遇到了麻烦。但我更喜欢从 refid 中剪切 insert="false" update="false" 并将其粘贴到 属性中,这解决了我的问题。谢谢你的建议。祝你好运
猜你喜欢
  • 1970-01-01
  • 2012-11-08
  • 2015-09-27
  • 2021-03-03
  • 2013-11-30
  • 2017-04-12
  • 1970-01-01
  • 2012-02-27
相关资源
最近更新 更多