级联或不级联? (“对象引用未保存的瞬态实例”错误)

时间:2010-07-16 14:42:29

标签: c# nhibernate orm nhibernate-mapping many-to-many

首先,我昨天试图提出类似的问题(NHibernate many-to-many relationship question: can select, can't update),但经过一个调试之夜后,我希望能更好地(右边?)方式改写一个问题。如果我做错了 - 请告诉 - 我会删除帖子。

以下是一个真实问题的描述:

给定USERROLEUSER_ROLE表,其中用户角色和多对多单向关系分别。目前,用户有一包角色,就是这样:

用户

  <class name="User" lazy="false" table="Users">
    <id name="Id" type="int">
      <generator class="native"/>
    </id>
    <version name="m_lastChanged" access="field" column="LastChanged" generated="never" type="int"/>

    <property name="Name" />

    <bag name="RoleList" table="User_Role" lazy="false" collection-type="Roles">
      <key column="UserId" foreign-key="Id"/>
      <many-to-many class="Role" column="RoleId"/>
    </bag>

  </class>

角色(目前很少有人):

  <class name="Role" lazy="false" table="Roles">
    <id name="Id" type="int">
      <generator class="native"/>
    </id>
    <version name="m_lastChanged" access="field" column="LastChanged" generated="never" type="int"/>

    <property name="Name" />
    <property name="Description" />
  </class>

角色表

CREATE TABLE [Roles] (
[Id] INTEGER NOT NULL PRIMARY KEY,
[Name] text  NOT NULL,
[LastChanged] INT NOT NULL DEFAULT(0)
);

CREATE UNIQUE INDEX uidxUserName ON Roles (Name COLLATE NOCASE);

USER TABLE

CREATE TABLE [Users] (
[Id] INTEGER NOT NULL PRIMARY KEY,
[Name] text NOT NULL,
[LastChanged] INT NOT NULL DEFAULT(0)
);

CREATE UNIQUE INDEX uidxRoleName ON Users (Name COLLATE NOCASE);

USER_ROLE TABLE

CREATE TABLE [User_Role] (
[UserId] INTEGER NOT NULL,
[RoleId] INTEGER NOT NULL,
[LastChanged] INT NOT NULL DEFAULT(0),
PRIMARY KEY (UserId, RoleId),
FOREIGN KEY (UserId) REFERENCES Users(Id),
FOREIGN KEY (RoleId) REFERENCES Roles(Id)
);

当提取用户时(我正在跟踪SQL查询) - 它的关系和角色也被提取:

SELECT
    rolelist0_.UserId as UserId1_,
    rolelist0_.RoleId as RoleId1_,
    role1_.Id as Id2_0_,
    role1_.LastChanged as LastChan2_2_0_,
    role1_.Name as Name2_0_,
    role1_.Description as Descript4_2_0_
FROM
    User_Role rolelist0_
left outer join
    Roles role1_
        on rolelist0_.RoleId=role1_.Id
WHERE
    rolelist0_.UserId=@p0;
@p0 = 2

SELECT
    user0_.Id as Id3_0_,
    user0_.LastChanged as LastChan2_3_0_,
    user0_.Name as Name3_0_,
    user0_.Password as Password3_0_,
    user0_.FullName as FullName3_0_,
    user0_.EMail as EMail3_0_,
    user0_.PhoneNumber as PhoneNum7_3_0_,
    user0_.Description as Descript8_3_0_
FROM
    Users user0_
WHERE
    user0_.Id=@p0;
@p0 = 2

问题出现:当我尝试保存 User 然后深入调试器时,NHibernate会检查 LastUpdated 的值< em> Role 对象并抛出 NHibernate.TransientObjectException 对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例),告诉我需要先保存角色。虽然这个角色仍未修改。

我已尝试在用户上应用“save-update”“all”以及其他类型的级联(无更改)在获取时,但是当保存用户时,它首先尝试保存角色,并且我得到一个例外,即违反了角色唯一性约束。

所以,如果合适的话,你能指出我在这里想念的是什么吗?

更新:意外地以下列方式修改了Role映射(添加了unsaved-value="undefined"):

<version name="m_lastChanged" access="field" column="LastChanged" unsaved-value="undefined" generated="never" type="int"/>

查询似乎没问题。 这是正确/最佳的解决方案,请

1 个答案:

答案 0 :(得分:0)

因此,为了简化长篇故事(并且感谢Ayende),版本字段LastUpdated应初始化为1,而不是0。然后它全都用一首可爱的交响曲来协调。

令人难以置信的是,在一个位中可以携带多少差异:)