nHibernate много-ко-многим сопоставления и отложенной загрузки - PullRequest
3 голосов
/ 09 июня 2011

У меня проблема с ассоциацией «многие ко многим» и сессией в nHibernate в моем веб-приложении.

Объект, с которым я работаю, всегда поддерживал соединение с сеансом, хотя и подключается к серверу и обратно.Никогда не было проблем.До сих пор.Я добавил в свой класс новую ассоциацию «многие ко многим».

Вот это отображение «многие ко многим» (имена изменены, чтобы сделать их более понятными):

 <bag name="ProductsToCategory" table="Tab_ProductsToCategory"" cascade="all-delete-orphan">
      <key column="ProductID" />
      <many-to-many class="CategoryClass" column="CategoryID" />
 </bag>

Когда я запускаю код, он работает при начальной загрузке.Однако последующие обращения к серверу, который обращается к этому объекту (объект поддерживается в веб-сеансе), приводят к разрыву этой коллекции и выдаче этой ошибки:

не удалось лениво инициализировать коллекцию, нет сеанса илисессия была закрыта

Странно.Я задавался вопросом, есть ли что-то об этом, являющемся ассоциацией многих ко многим, которая вызывает проблему?Это «многие ко многим» добавляется только к этому классу, а не к классу на другом конце отображения, «CategoryClass», так как он мне там не нужен. Объект, кажется, в порядке, пока я не добавлю это отображение.

Есть идеи?

ТАКЖЕ: Я попытался просто проверить, больше не находится ли объект в сеансе.Это не так.Поэтому я звоню: session.refresh(productClass) и все корректно обновляется, включая мое проблемное отображение.Тем не мение.Он загружает каждый предмет в коллекции ДВАЖДЫ!коллекция содержит в два раза больше элементов, чем в базе данных, каждый элемент отображается дважды.Если бы я мог получить ответ на эту проблему, предыдущий вопрос не имеет большого значения.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.Приветствия.

1 Ответ

5 голосов
/ 12 июня 2011

Я предполагаю, что вы используете шаблон сеанса для запроса в веб-приложении. Ленивая загрузка требует, чтобы сеанс, который первоначально использовался для загрузки родительского объекта, все еще оставался открытым при обращении к его дочерней коллекции. Вы создаете новый сеанс для каждого HTTP-запроса, поэтому объекты, сохраненные в состоянии сеанса в первом запросе, являются отделенными объектами во втором запросе. Вот почему вы получаете сообщение об ошибке и почему во втором запросе исходный объект отсутствует в сеансе.

Чтобы исправить это, вызовите ISession.Lock при доступе к объекту из состояния сеанса.

var myProductClass = GetProductClassFromSession(); // whatever method you use to do this
session.Lock(myProductClass, LockMode.None);

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

Кстати, вы, вероятно, не хотите cascade="all-delete-orphan" в отображении «многие ко многим». Это приведет к удалению объектов категории при удалении продукта.

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