开发者

NHibernate cascade delete

Let me begin with showing the mapping:

Parent:

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

Child:

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

In other words: a profile can have many communication channels.

On the UI (user-interface [ASP.NET Webforms]) the following event is fired (deleting a profile with communication channels attached to it) :

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

(the DaoFactory is located in one project file and the UI is an ASP.NET Website)

This code works.

IMPORTANT: the code is using the NHibernate 'open-session-in-view' pattern.

I have a service implementation that fires the same code (deleting a profile with communication channels). Some code...

            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();

Where 'EndTransaction()' does a 'commit'. I test this code with an 'unit test':

    [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);
    }

This code fails. The following error is bugging me:

The DELETE statement conflicted with the REFERENCE constraint "R2_PROFIEL". The conflict occurred in database "CRM_ontw", table "dbo.COMMUNICATIEKANAAL", column 'SEK_PROFIEL'. The statement has been terminated.

This means that the cascade didn't happen at all. Executed from the UI it works, but when fired from the 'service implementation', it fails. Any ideas or suggestions that could help me?

Thanks in advance


Edit: the following generic code delete's an object

    public void Delete(T entity)
    {
        try
        {
            OnDelete(entity);
开发者_如何学C        }
        catch (Exception)
        {
            SessionManager.Instance.RollbackTransactionOn(SessionFactoryConfigPath);
            throw;
        }
        session.Delete(entity);
    }

Setting the all-delete-orphan doesn't fix the problem.


I've found the problem. The NHibernate 'open-session-in-view' pattern closes the session after commiting the changes to the database (so when the requests ends, the sessions gets closed):

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

But my EndTransaction() implementation on the service side didn't.

So with a few tweaks I created this EndTransaction() method:

public void EndTransaction()
{
    try
    {
        SessionManager.Instance.CommitTransactionOn(SessionFactoryConfigPath);
    }
    finally
    {
        SessionManager.Instance.CloseSessionOn(SessionFactoryConfigPath);
    }
}


Try setting cascade="delete" to cascade="all-delete-orphan"

Also, ensure that in both instances, the parent is being read and saved by the same ISession instance. As someone commented, we need to see the implementation of your .Delete() method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜