3

让我从显示映射开始:

家长:

<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" />

换句话说:一个配置文件可以有许多沟通渠道。

在 UI(用户界面[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 位于一个项目文件中,UI 是一个 ASP.NET 网站)

此代码有效。

重要提示:代码使用 NHibernate 'open-session-in-view' 模式。

我有一个触发相同代码的服务实现(删除带有通信渠道的配置文件)。一些代码...

            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并不能解决问题。

4

2 回答 2

2

我发现了问题。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);
    }
}
于 2011-03-01T13:54:20.537 回答
0

尝试设置cascade="delete"cascade="all-delete-orphan"

此外,确保在这两种情况下,父级都被读取保存同一个ISession实例正如有人评论的那样,我们需要查看您的.Delete()方法的实现。

于 2011-02-28T19:13:17.567 回答