2014-06-18 28 views
0

所以我的数据模型是这样的:功能NHibernate级联保存问题,在独特的藏品非唯一对象

标题 - (有很多) - >任务 - (拥有0或1) - > COMPONENT

然而,即使每一个任务可能只有一个组件,组件可与各种任务相关联......当我执行saveOrUpdate()方法我收到以下错误:

“不同的对象有相同的标识符值已经与会话相关联“

我验证为true,因为多个TASK具有相同的COMPONENT(不同的对象实例,但内部相同)。这最初是从数据库中读出的,这是我映射的源头,但显然我错过了一些东西以便保存回数据库。

希望有人能指出我正确的方向,因为我认为做到这一点的唯一方法是分别保存COMPONENTs以冲刷每个任务之间的会话。

这里是我的映射:

HEADER

public class Header_ORM: ClassMap<Header> { 
    public Header_ORM() { 
    Table("HEADER"); 
    Id(x => x.HeaderID).Length(8); 
    . 
    . More Mappings 
    . 
    HasMany<Task>(x => x.Tasks) 
     .Cascade.SaveUpdate() 
     .KeyColumns.Add("HeaderID") 
     .LazyLoad(); 
} 

TASK

public class Task_ORM : ClassMap<Task> { 
    public Task_ORM() { 
    Table("TASK"); 
    CompositeId(x => x.ID) 
     .KeyProperty(x => x.HeaderID, x => x.Length(8)) 
     .KeyProperty(x => x.TaskID, x => x.Length(2)); 
    Map(x => x.HeaderID).Length(8).ReadOnly(); 
    Map(x => x.TaskID).Length(2).ReadOnly(); 
    . 
    . More Mappings 
    . 
    References(x => x.EquipmentComponent) 
    .Cascade.SaveUpdate() 
    .NotFound.Ignore() 
    .LazyLoad() 
    .Columns(
     "A", 
     "B", 
     "C", 
     . 
     . More Columns 
     . 
    ); 
    } 
} 

COMPONENT

public class Component_ORM : ClassMap<Component> { 
    public Component_ORM() { 
    Table("COMPONENT"); 
    CompositeId(x => x.ID) 
     .KeyProperty(x => x.A, x => x.Length(3)) 
     .KeyProperty(x => x.B, x => x.Length(6)) 
     .KeyProperty(x => x.C, x => x.Length(6)) 
     . 
     . More Composite Key Columns 
     . 
    Map(x => x.A).Length(3).ReadOnly(); 
    Map(x => x.B).Length(6).ReadOnly(); 
    Map(x => x.C).Length(6).ReadOnly(); 
    . 
    . More Mappings 
    . 

    } 
} 

回答

0

好了,所以我也基本上是我说我以为会工作(和它):

using (ITransaction transaction = session.BeginTransaction()) { 
    foreach (WorkOrderTask t in WorkOrder.Tasks) { 
     if (t.EquipmentComponent != null) { 
     session.SaveOrUpdate(t.EquipmentComponent); 
     session.Flush(); 
     session.Clear(); 
     } 
    } 
    session.SaveOrUpdate(WorkOrder); 
    transaction.Commit(); 
    } 

先保存每个组件,刷新并清除保存之间的会话。这是必需的,因为我得到了这个有状态的会议。看起来更合适的解决方案是使用无状态会话。我还没有进一步调查这种方法,因为我反正无法使用它,但值得注意。