NHibernate и работа с коллекциями

Столкнулся со странной проблемой, связанной с работой с коллекциями Many-to-Many, реализованной с помощью IDBag в NHibernate.
Как известно, в этом случае на уровне базы данных связь many-to-many представлена отдельной таблицей, в которую добавлены ссылки на оба связанных объекта и каждой записи назначается уникальный идентификатор. В моем случае идентификатор назначается на основе sequence.

Чтобы воспроизвести проблему делаем простое действие. Удаляем один из объектов из коллекции и тут же добавляем его обратно. Пытаемся сохранить данные и получаем исключение. NHibernate пытается создать запись в промежуточной таблице но не назначает ей уникальный идентификатор (пытается записать null). Значение из Sequence также не берется. Анализ исходных текстов привел к неутешительному выводу — мы не можем повлиять на процесс сохранения и устранить проблему.

Дело в том, что NH пытается устранить лишние с его точки зрения запросы к базе. Так как логически связь между двумя объектами остается неизменной, одна часть NH (которая находит изменения в коллекции) считает , что при сохранении данных эта запись сохранена не будет и не назначает ей ID. То есть не учитывается то, что запись на самом деле новая. Другая же часть NH ничего не знает о том, какие связи существовали ранее и просто пытается сохранить все объекты, которые описывают связи полагаясь на то, что все ключевые поля там уже назначены. И мы получаем ошибку 🙂

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

P.S. В процессе исследования проблемы было найдено подтверждение на форуме разработчиков. Похоже, что в ближайшее время ее решать не будут.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *