Помогите сопоставить сумку с NHibernate, предметы в сумке не сохраняются - PullRequest
0 голосов
/ 13 сентября 2011

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

У меня есть Пересечение классов, которое относится к устройству базового типа и содержит Список зон, еще один мой класс. Каждое пересечение может иметь несколько зон, но только 1 пересечение может быть назначено определенной зоне.

Мое сопоставление для устройства / пересечения выглядит следующим образом:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="EMTRAC.Devices.Device, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Device`" lazy="false">
<id name="PK" type="System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="PK" />
  <generator class="identity" />
</id>
<many-to-one class="EMTRAC.Connections.Connection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="LocalConnection" lazy="false" cascade="all">
  <column name="LocalConnection_id" />
</many-to-one>
<many-to-one class="EMTRAC.Connections.Connection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Connection" lazy="false" cascade="all">
  <column name="Connection_id" />
</many-to-one>
<many-to-one class="EMTRAC.Packets.Packet, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Configuration" lazy="false" cascade="all">
  <column name="Configuration_id" />
</many-to-one>
<joined-subclass name="EMTRAC.Intersections.Intersection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" lazy="false">
  <key>
    <column name="Device_id" />
  </key>
  <bag name="Zones" cascade="all-delete-orphan">
    <key>
      <column name="Intersection_id" />
    </key>
    <one-to-many class="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </bag>
  <many-to-one class="EMTRAC.Intersections.Streets, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Streets" lazy="false" cascade="all">
    <column name="Streets_id" />
  </many-to-one>
  <many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Position" lazy="false" cascade="all">
    <column name="Position" />
  </many-to-one>
</joined-subclass>

И мое отображение для класса Zone выглядит следующим образом:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Zone`" lazy="false">
<id name="ID" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="PK" />
  <generator class="identity" />
</id>
<property name="Active" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="Active" />
</property>
<property name="Dir" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="Dir" />
</property>
<property name="IntID" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="IntID" />
</property>
<property name="Width" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="Width" />
</property>
<many-to-one class="EMTRAC.Headings.Heading, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Heading" cascade="all">
  <column name="Heading_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Start" cascade="all">
  <column name="Start_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Finish" cascade="all">
  <column name="Finish_id" />
</many-to-one>

Теперь, если я создаю объект Zone и сохраняю его в базе данных, все сохраняется нормально, а поле Intersection_Id для ссылки на объект Intersection является нулевым, как и ожидалось. Однако, как только я добавляю этот объект Zone к пересечению и сохраняю пересечение, он не связывает зону с пересечением через поле Intersection_id, и загрузка пересечения не содержит никаких зон в списке зон.

Если я сохраню Пересечение без предварительного сохранения зоны, Пересечение сохранится нормально, но Зона не будет сохранена.

Глядя на SQL для сеанса. Сохранение (пересечение), я не вижу ничего отправляемого, чтобы попытаться сохранить Зону.

Кроме того, если я сохраню перекресток, попробуйте

foreach(Zone z in intersection.Zones) session.Save(z);

NHibernate не выполняет SQL и не сохраняет зону.

Это, наверное, что-то маленькое, что мне не хватает. Есть идеи?

EDIT

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

Так или иначе, решение было тройным.

Сначала я должен был убедиться, что Зона была сохранена, прежде чем сохранять пересечение со списком, содержащим Зону. Если вы не сохраняете Зону при вызове Flush, как описано ниже, вы получаете сообщение об ошибке, когда он пытается связать Зону с Пересечением, но не находит запись Зоны в таблице для Зон.

Это было достигнуто путем вызова Session.Save (зона), где Session является ISession.

После того, как Зона была сохранена, я затем сохранил Пересечение, используя метод, описанный выше, но вызвав Session.Save (пересечение).

Последний бит, который решил проблему, состоял в том, что после того, как я сохранил пересечение, мне пришлось вызвать Session.Flush () для сеанса ISession, который затем связал зону с пересечением.

Это решило проблему, и теперь все сохранено, загружено и правильно связано.

Что делает ISession.Flush () в фоновом режиме, который требовал, чтобы я вызывал его, чтобы собрать все воедино, и почему не все было сохранено, просто вызывая Session.Save (пересечение) с каскадным набором для пакета?

1 Ответ

0 голосов
/ 15 сентября 2011

в NH Updates и Inserts обычно пакетируются и выполняются на Session.Flush(), но, так как вы используете identity NH должен немедленно выполнить INSERT для генерации идентификатора, но пакетирует Updates.для повышения производительности и включения пакетной обработки существуют другие стратегии генерации ключей (GUID, HiLo, ...).

эти зоны вообще не вставляются inverse может помочь

<bag name="Zones" cascade="all-delete-orphan" inverse="true">
...