具有多个关系的2个类的NHibernate映射

时间:2009-02-03 09:56:37

标签: nhibernate

尝试使用NHibernate来持久保存2个对象之间有多个关联的新实例时,会出现以下错误:

 NHibernate.Exceptions.GenericADOException: could not insert: [MyProject.BusinessEntities.Client][SQL: INSERT INTO dbo.Client (Version, CurrentEvent_ClientEvent_Id, EntityType, Id) VALUES (?, ?, 'MyProject.BusinessEntities.Client', ?)] --->  System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK328F067A46E318FD". The conflict occurred in database "DatabaseName", table "dbo.ClientEvent", column 'ClientId'.

方案如下:

我有2个类(为了清楚起见,我已重命名):Client和ClientEvent。 客户端有一个名为Events的属性,其类型为List。 ClientEvent包含一个属性“Client”,它是返回Client对象的反向关联。 此外,Client类还有另一个名为CurrentEvent的属性,它包含对ClientEvents集合中某个项的引用。

Client.hbm.xml包含:

<bag name="ClientEvents" access="field.camelcase-underscore" inverse="true" cascade="save-update">
    <key column="Client_Id"/>
    <one-to-many class="MyProject.BusinessEntities.ClientEvent, MyProject.BusinessEntities" />
</bag>
<many-to-one name="CurrentEvent" access="property" class="MyProject.BusinessEntities.ClientEvent, MyProject.BusinessEntities" column="CurrentEvent_ClientEvent_Id" cascade="save-update" />

ClientStatusRecord.hbm.xml包含:

<many-to-one name="Client" access="property" class="MyProject.BusinessEntities.Client, MyProject.BusinessEntities" column="Client_Id" cascade="save-update" />

我从映射中自动生成数据库模式,两个表中的外键都可以为空。

我使用以下代码来持久保存新的Client和ClientRecord(再次简化为删除所有会话管理gumpf)

var newClient = CreateNewClient();
var newEvent = CreateNewEvent();
newEvent.client = newClient; // ensure the reverse association is set
newClient.Events.Add(newEvent);
session.SaveOrUpdate(newClient);
session.Flush();

看一下NHibernate的SQL输出,它似乎试图在保存ClientEvent记录之前保存Client记录,试图将ClientEvent Id插入到因为ClientEvent记录尚不存在而失败的外键中< / p>

问题

  • 有没有人让它在nhibernate持久存在具有多种关系的对象的情况下工作?
  • 如果是这样,映射应该是什么样的?
  • 我可以尝试的任何建议吗?

对于长篇文章

抱歉

2 个答案:

答案 0 :(得分:3)

谢谢,我尝试了在Client和ClientEvent映射中将cascade属性设置为Save-Update或None的所有组合,但没有成功。

然而,通过从头开始逐步构建我的映射,我弄清楚问题是什么....我在Client和ClientEvent对象上设置Id而不是让NHibernate在对象是时生成值持续存在。在大多数情况下,如果在持久化对象之前显式设置Id似乎并不重要。但是,在这种情况下,似乎NHibernate错误地解析了对象需要持久化的顺序,并尝试持久化引用尚不存在的ClientEvent的客户端记录。

解决方案:让NHibernate生成对象的标识符

答案 1 :(得分:0)

我想这是关于 cascade ,尝试更改映射中的级联值。 不是100%肯定,但是,尝试在多对一映射中将级联设置为“无”