NHibernate Evict по типу и идентификатору из кэша первого уровня

У меня есть объект Nhibernate с именем Car, этот объект Car имеет коллекцию PersietentBag IList с именем Doors, все в отложенной загрузке.

если я это сделаю (НА СЕССИИ 1)

int singleDoor = Car.Doors[0];

самые ленивые коллекции загружаются из базы данных, и связанные объекты добавляются в кеш первого уровня, у меня будет в кеше первого уровня N объектов Car и N Doors, загруженных из db.

С другой стороны (в другой части кода В СЕССИИ 2) я загружаю те же объекты Car и выполняю то же задание

int singleDoor = Car,Doors[0];

и я выселяю машину и все объекты Door(s) из SESSION2

я изменяю состояние этих объектов и хочу прикрепить объекты doscontected к SESSION1 для сохранения и выполнения

mySession.Update(Car);

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

Боту трудно найти старый объект для удаления, как я могу ВЫСЕЛИТЬ старые объекты или очистить кеш 1-го уровня (только по типу и идентификатору) или удалить старые объекты из кеша и обновить то, что я хочу?

заранее спасибо.


person manuellt    schedule 22.05.2012    source источник


Ответы (1)


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

Ответ на ваш вопрос заключается в использовании (в сеансе 1) session.Evict(car), однако это не лучший подход - я бы предпочел использовать session.Merge(car), который будет обновлять постоянный объект в сеансе 1 без выбрасывание исключения о другом объекте с тем же идентификатором.

person Martin Ernst    schedule 22.05.2012
comment
Спасибо, я исправил ошибку, это кеш 1-го уровня, на самом деле session.Evict(Car) - не лучший подход, однако у меня нет под рукой старого объекта Car для Evict, с подходом Merge, если у меня есть изменения состояния в старом автомобиле, изменения состояния 2 автомобилей слились? или старые изменения состояния автомобиля теряются? мне нужно отказаться от старого состояния автомобиля, спасибо заранее. - person manuellt; 22.05.2012
comment
Вы можете сделать session.Get‹Car›(id), чтобы получить его из сеанса, а затем исключить его, однако, если он изначально не был в сеансе, это вызвало бы ненужную нагрузку на базу данных. Session.Merge перезапишет старое состояние автомобиля новым, т.е. он отбросит старое состояние автомобиля (если вы хотите, чтобы он также объединил любые дочерние коллекции, вам нужно установить каскад сбора для слияния) - person Martin Ernst; 22.05.2012