Использование каскада в NHibernate - PullRequest
2 голосов
/ 16 января 2011

У меня есть два класса, назовите их Обезьяна и Банан, с двунаправленными отношениями один-ко-многим

Monkey monkey = new Monkey();
Banana banana = new Banana();
monkey.Bananas.Add(banana);
banana.Monkey = monkey;
hibernateService.Save(banana);

Когда я запускаю этот кусок кода, я хочу, чтобы и обезьяна, и банан сохранялись. Тем не менее, он сохраняется только тогда, когда я явно сохраняю обезьяну, а не наоборот. Первоначально это имело смысл, поскольку только мой Monkey.hbm.xml имел отображение с cascade="all".

<set name="Bananas" inverse="true" cascade="all">
  <key column="Id"/>
  <one-to-many class="Banana"/>
</set>

Я подумал, что мне просто нужно добавить следующее в мой файл Banana.hbm.xml:

<many-to-one name="Monkey" column="Id" cascade="all" />

К сожалению, это привело к ошибке Parameter index is out of range, когда я попытался запустить фрагмент кода. Я исследовал эту ошибку и нашел этот пост , но я все еще не вижу, что я делаю неправильно. Насколько я могу судить, отношения отображаются по одному разу на каждой стороне. Для полного раскрытия вот два файла сопоставления:

Monkey.hbm.xml

<class name="Monkey" table="monkies" lazy="true">
    <id name="Id">
      <generator class="increment" />
    </id>
    <property name="Name" />
    <set name="Bananas" inverse="true" cascade="all">
      <key column="Id"/>
      <one-to-many class="Banana"/>
    </set>
</class>

Banana.hbm.xml

<class name="Banana" table="bananas" lazy="true">
    <id name="Id">
      <generator class="increment" />
    </id>
    <property name="Name" />
    <many-to-one name="Monkey" column="Id" cascade="all" />
</class>

Ответы [ 3 ]

3 голосов
/ 16 января 2011

Индекс параметра выходит за пределы допустимого диапазона из-за ваших отображений.Вы идентифицировали Id как первичный и внешний ключи в отношениях.

1 голос
/ 16 января 2011

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

Я предполагаю, что вы испортиливнешние ключи.Вы говорите, что это отношение «один ко многим», так что это означает, что у Banana есть внешний ключ к таблице обезьян, верно?Стандартным наименованием для этого столбца внешнего ключа будет MonkeyID, и это то, что, по-видимому, отсутствует в ваших сопоставлениях - все имена столбцов выглядят как ID.Джеймс Иде ответил похожими словами, а затем вы сказали: «Идентификатор - это имя столбца первичного ключа в обеих таблицах. Как должны выглядеть мои сопоставления отношений?»- действительно, вполне нормально, чтобы имя столбца первичного ключа было идентификатором в обеих таблицах, но это все еще не описывает отношение .Как я упоминал выше, вам нужен внешний ключ для отношений.

Вы должны обнаружить, что проблема каскада решается сама собой, как только вы исправите свои отношения.Поведение, которое люди обычно хотят получить от каскада, - это каскадное удаление от родителя к потомку, а не наоборот, и в этом случае вы, вероятно, захотите использовать cascade = "save-update" для элемента многие-к-одному вместо каскада.= "all".

Наконец, в качестве бесстыдного штекера, вы рассматривали возможность попробовать Fluent NHibernate ?Возможно, вам будет легче учиться, чем синтаксису hbm xml.

1 голос
/ 16 января 2011

Детское отображение (банан) не обязательно должно иметь атрибут каскада. Если один банан удален, у обезьяны могут остаться другие бананы, но когда обезьяна будет заменена, все ее бананы должны быть изменены соответствующим образом, поэтому только у обезьяны должен быть атрибут каскада

...