кэшированная коллекция не аннулируется Nhibernate - PullRequest
4 голосов
/ 09 сентября 2011

У меня есть два объекта - ContentPage, который имеет коллекцию ChildLinks.

ContentPage
-----------
ID
Title

ChildLink
----------
ID
ParentPageID [ContentPage]
ChildPageID [ContentPage]
Priority

Свойство ContentPage.ChildLinks использует кэш 2-го уровня.Я использую Fluent NH для настройки Nhibernate и использую Nhibernate 3.1.Кэш установлен как «Чтение-Запись» как для коллекции, так и для класса «ChildLink».

Я заметил, что всякий раз, когда я удаляю ChildLink, кэш коллекции не аннулируется.Таким образом, когда я вызываю ContentPage.ChildLinks, я получаю сообщение об ошибке:

no row with the given identifier exists

Я отключил кэш, и он работает хорошо.Разве кеш не должен быть автоматически признан недействительным?Я использую SysCache в качестве поставщика кеша и MySQL в качестве базы данных.

Заранее спасибо!

1 Ответ

2 голосов
/ 01 марта 2012

У меня была такая же проблема, и я могу найти следующую статью, которая решила мою проблему:

Коллекции с обратным отображением и кэш-память второго уровня NHibernate

В основном, если вы сопоставили свои коллекции как inverse , при удалении дочернего элемента вы также должны обязательно явно удалить его из родительской коллекции, иначе состояние кеша станет недействительным после удаления ребенок. Первое, что нужно проверить - действительно ли отношения должны быть обратными.

Предполагая, что обратное необходимо или желательно , и используя ваш пример:

Вместо чего-то вроде:

Session.Delete(ChildLink);

Вы должны сделать:

ContentPage.ChildLinks.Remove(ChildLink);
ChildLink.ParentPage = null;
Session.Delete(ChildLink);

Вам также может понадобиться явно сохранить объект ContentPage на этом этапе, это зависит от настроек очистки сеанса.

Я использую методы в своих сущностях для управления такими обратными отношениями, например:

public ChildLink
{
    public ContentPage ParentPage {get;set;}

    public void AddToPage(ContentPage addTo)
    {
        addTo.ChildLinks.Add(this);
        this.ParentPage = addTo;
    }

    public void RemoveFromPage()
    {
        ParentPage.ChildLinks.Remove(this);
        this.ParentPage = null;
    }

}

А затем при удалении дочернего объекта:

ChildLink.RemoveFromPage();
Session.Delete(ChildLink);
...