首先让我展示一下映射:
父:
<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'。声明一直如此 终止。
这意味着级联根本没有发生。从用户界面执行工作,但是当从“服务实施”触发时,失败。任何可以帮助我的想法或建议?
提前致谢
编辑:以下通用代码删除对象
public void Delete(T entity)
{
try
{
OnDelete(entity);
}
catch (Exception)
{
SessionManager.Instance.RollbackTransactionOn(SessionFactoryConfigPath);
throw;
}
session.Delete(entity);
}
设置all-delete-orphan
并不能解决问题。
答案 0 :(得分: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);
}
}
答案 1 :(得分:0)
尝试将cascade="delete"
设为cascade="all-delete-orphan"
此外,请确保在两个实例中,父级由同一ISession
实例读取并保存。正如有人评论,我们需要看到您的.Delete()
方法的实施。