Отображения NHibernate для 2 классов, которые имеют несколько отношений - PullRequest
1 голос
/ 03 февраля 2009

Я получаю следующую ошибку при попытке использовать NHibernate для сохранения нового экземпляра 2 объектов, которые имеют более одной связи между ними:

 NHibernate.Exceptions.GenericADOException: could not insert: [MyProject.BusinessEntities.Client][SQL: INSERT INTO dbo.Client (Version, CurrentEvent_ClientEvent_Id, EntityType, Id) VALUES (?, ?, 'MyProject.BusinessEntities.Client', ?)] --->  System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK328F067A46E318FD". The conflict occurred in database "DatabaseName", table "dbo.ClientEvent", column 'ClientId'.

Сценарий выглядит следующим образом:

У меня есть 2 класса (которые я переименовал для ясности): Client и ClientEvent. У клиента есть свойство с именем Events, которое имеет тип List. ClientEvent содержит свойство «Client», которое является обратной связью с объектом Client. Кроме того, класс Client имеет другое свойство CurrentEvent, которое содержит ссылку на один из элементов в коллекции ClientEvents.

Client.hbm.xml содержит:

<bag name="ClientEvents" access="field.camelcase-underscore" inverse="true" cascade="save-update">
    <key column="Client_Id"/>
    <one-to-many class="MyProject.BusinessEntities.ClientEvent, MyProject.BusinessEntities" />
</bag>
<many-to-one name="CurrentEvent" access="property" class="MyProject.BusinessEntities.ClientEvent, MyProject.BusinessEntities" column="CurrentEvent_ClientEvent_Id" cascade="save-update" />

ClientStatusRecord.hbm.xml содержит:

<many-to-one name="Client" access="property" class="MyProject.BusinessEntities.Client, MyProject.BusinessEntities" column="Client_Id" cascade="save-update" />

Я автоматически генерирую схему базы данных из сопоставлений, и внешние ключи в обеих таблицах обнуляются.

Я использую следующий код для сохранения нового клиента и ClientRecord (снова упрощено, чтобы удалить все gumpf управления сеансом)

var newClient = CreateNewClient();
var newEvent = CreateNewEvent();
newEvent.client = newClient; // ensure the reverse association is set
newClient.Events.Add(newEvent);
session.SaveOrUpdate(newClient);
session.Flush();

Взглянув на вывод SQL из NHibernate, он, похоже, пытается сохранить запись клиента перед сохранением записи ClientEvent, пытается вставить идентификатор ClientEvent во внешний ключ, который завершается ошибкой, поскольку запись ClientEvent еще не существует

Вопросы

  • Кто-нибудь заставил его работать там, где nhibernate сохраняет объект с несколькими связями?
  • Если это так, как должны выглядеть сопоставления?
  • Есть предложения, что я могу попробовать?

Извините за длинный пост

Ответы [ 2 ]

3 голосов
/ 04 февраля 2009

Спасибо, я попробовал все комбинации установки свойства каскада для Save-Update или None в сопоставлениях Client и ClientEvent, но безуспешно.

Однако, создавая шаг за шагом мои сопоставления с нуля, я выяснил, в чем проблема ... Я устанавливал Id для объектов Client и ClientEvent, а не позволял NHibernate генерировать значения во время объектов сохранялось. В большинстве случаев, кажется, не имеет значения, если вы явно устанавливаете Id до сохранения объектов. Однако в этом случае кажется, что NHibernate неправильно разрешает порядок, в котором объекты должны быть сохранены, и пытается сохранить запись Client, ссылающуюся на ClientEvent, который еще не существует.

Решение: Пусть NHibernate сгенерирует Идентификатор для объектов

0 голосов
/ 03 февраля 2009

Полагаю, речь идет о каскаде , попробуйте изменить значения каскадов в отображениях. Не уверен на 100%, но попробуйте установить для каскадов значение «Нет» во многих сопоставлениях «один на один»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...