2009-02-03 113 views
1

我得到试图使用NHibernate的坚持2个对象之间有多个协会的新实例时,出现以下错误: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" /> 

我自动生成的映射数据库架构,以及两个表中的外键都是可空的。

我使用下面的代码坚持一个新的客户端和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记录之前保存的客户记录,试图插入ClientEvent标识成失败外键,因为ClientEvent记录不存在尚未

问题

  • 有没有人知道nhibernate在多重关系中持续存在对象?
  • 如果是这样,映射应该是什么样子?
  • 我可以尝试的任何建议吗?

对不起,冗长的职位

回答

3

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

但是,通过从头开始逐步构建我的映射,我找出了问题所在......我在Client和ClientEvent对象上设置Id,而不是让NHibernate在对象时生成值坚持下去。在大多数情况下,如果您在保留对象之前显式设置Id,则似乎并不重要。但是,在这种情况下,NHibernate似乎错误地解决了对象需要保存的顺序,并尝试保留引用ClientEvent的客户端记录不存在。

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

0

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