NHibernate каскадный удалить - PullRequest
3 голосов
/ 28 февраля 2011

Позвольте мне начать с отображения сопоставления:

Родитель:

<bag name="Communicatiekanalen" table="COMMUNICATIEKANAAL" inverse="true" cascade="delete" lazy="true" >
        <key column="SEK_PROFIEL"/>
        <one-to-many class="Crm.Hibernate.Communicatiekanaal,Crm.Hibernate" />
</bag>

Ребенок:

<many-to-one name="SekProfiel" column="SEK_PROFIEL" class="Crm.Hibernate.Profiel,Crm.Hibernate" />

Другими словами: профиль может иметь много каналов связи.

В пользовательском интерфейсе (пользовательский интерфейс [ASP.NET Webforms] ) возникает следующее событие (удаление профиля с подключенными к нему каналами связи):

    var profielDao = CrmConfiguration.GetDaoFactory().GetProfielDao();
    var profiel = profielDao.GetById(2194, true); //lets say '2194' is an ID that exists
    profielDao.Delete(profiel);

(DaoFactory находится в одном файле проекта, а пользовательский интерфейс - это веб-сайт ASP.NET)

Этот код работает.

ВАЖНО: код используетNHibernate 'open-session-in-view' pattern.

У меня есть реализация сервиса, которая запускает тот же код (удаление профиля с каналами связи).Какой-то код ...

            var daof = CrmConfiguration.GetDaoFactory();
            CrmSettings.Instance.UserID = user;
            var profielDao = daof.GetProfielDao();

            profielDao.BeginTransaction();
            var profiel = profielDao.GetById(CrmEntitiesToHibernate.ParseStringToId(profileId), true);
            profielDao.Delete(profiel);
            profielDao.EndTransaction();

Где EndTransaction () выполняет коммит.Я проверяю этот код с помощью «модульного теста»:

    [TestMethod]
    public void TestDeleteProfile()
    {
        //Getting a valid NEW profile
        var profile = GetSecundaryProfile();
        //Adding a communication channel to the profile
        CrmClient.AddCommunicationChannelForProfile(GetPlainCommunicationChannel(), profile.Id, CurrentUserId);
        //Calling the 'delete profile' method on the service --> FAIL - no cascade
        CrmClient.DeleteProfile(profile.Id, CurrentUserId);
    }

Этот код не выполняется.Следующая ошибка вызывает у меня ошибку:

Оператор DELETE конфликтует с ограничением REFERENCE "R2_PROFIEL".Конфликт произошел в базе данных "CRM_ontw", таблице "dbo.COMMUNICATIEKANAAL", столбце "SEK_PROFIEL".Утверждение было прекращено.

Это означает, что каскад не произошел вообще.Выполненный из UI , он работает , но при запуске из реализации службы 'он завершается с ошибкой .Любые идеи или предложения, которые могут мне помочь?

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


Редактировать: следующий универсальный код удаления это объект

    public void Delete(T entity)
    {
        try
        {
            OnDelete(entity);
        }
        catch (Exception)
        {
            SessionManager.Instance.RollbackTransactionOn(SessionFactoryConfigPath);
            throw;
        }
        session.Delete(entity);
    }

Установка all-delete-orphan не решает проблему.

Ответы [ 2 ]

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

Я нашел проблему. Шаблон NHibernate 'open-session-in-view' закрывает сеанс после фиксации изменений в базе данных (поэтому, когда запросы заканчиваются, сеансы закрываются):

        finally
        {
            // No matter what happens, make sure all the sessions get closed
            foreach (SessionFactoryElement sessionFactorySettings in openSessionInViewSection.SessionFactories)
            {
                SessionManager.Instance.CloseSessionOn(sessionFactorySettings.FactoryConfigPath);
            }
        }

Но моя EndTransaction() реализация на стороне службы не сделала.

Итак, с помощью нескольких настроек я создал EndTransaction() метод:

public void EndTransaction()
{
    try
    {
        SessionManager.Instance.CommitTransactionOn(SessionFactoryConfigPath);
    }
    finally
    {
        SessionManager.Instance.CloseSessionOn(SessionFactoryConfigPath);
    }
}
0 голосов
/ 28 февраля 2011

Попробуйте установить cascade="delete" в cascade="all-delete-orphan"

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

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