Каскадировать или не каскадировать? («объект ссылается на несохраненный временный экземпляр» ошибка) - PullRequest
2 голосов
/ 16 июля 2010

Во-первых, я пытался задать аналогичный вопрос вчера ( NHibernate вопрос многие-ко-многим: могу выбрать, не могу обновить ), но, надеюсь, после ночи отладки я смогу перефразировать вопрос лучше (правильно?). Если я делаю что-то не так - пожалуйста, скажите - я сотру пост.

Вот описание, за которым следует реальный вопрос:

Имеются таблицы USER, ROLE и USER_ROLE, в которых хранятся Users , Roles и однонаправленное отношение «многие ко многим» соответственно. В настоящее время Пользователь имеет мешок Роли и все:

USER

  <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>

ROLE (в настоящее время их очень мало):

  <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);

ТАБЛИЦА ПОЛЬЗОВАТЕЛЕЙ :

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

И тут возникает проблема : когда я пытаюсь сохранить Пользователь , то глубоко в отладчике NHibernate проверяет LastUpdated значение Роль объект и выбрасывает NHibernate.TransientObjectException ( объект ссылается на несохраненный временный экземпляр - сохраните временный экземпляр перед сбросом ), сообщив, что мне нужно сохранить Роль первая. Пока что роль еще не изменена.

Я пытался применить "save-update" и "all" и другие типы, каскадные для User (без изменений при извлечении) но затем при сохранении Пользователь сначала пытается сохранить Роль , и я получаю исключение, что ограничение уникальности роли нарушено.

Итак, если это уместно, не могли бы вы указать, что мне здесь не хватает, пожалуйста?

Обновление : случайно изменил отображение Role следующим образом (добавлено unsaved-value="undefined"):

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

Запросы вроде бы в порядке. Это правильное / лучшее решение, пожалуйста ?

1 Ответ

0 голосов
/ 27 июля 2010

Таким образом, для краткости (и благодаря Ayende ) поле версии LastUpdated должно быть инициализировано как 1, а не 0.Тогда все это звучит в прекрасной симфонии.

Так невероятно, сколько различий можно отнести в один бит:)

...