2014-06-18 4 views
0

그래서 내 데이터 모델은 다음과 같습니다 독특한 컬렉션 고유하지 않은 객체와 문제를 저장 캐스 캐 이드 :유창함 NHibernate에이

HEADER -> 작업 - - (0 또는 1을 가지고) - (많은이 있습니다)> COMPONENT

모든 작업이 하나 개의 구성 요소가 있더라도 그러나

, 구성 요소는 다양한 작업과 관련 ... 될 수있다 나는 될 saveOrUpdate()를 나는 다음과 같은 오류 얻을 수행 할 때 :

"다른 객체를 동일한 식별자 값이 이미 세션과 연결되어 있습니다. "

하나 이상의 작업에는 동일한 COMPONENT (다른 객체 인스턴스가 있지만 내부적으로 동일 함)가 있기 때문에 사실로 검증되었습니다. 이것은 처음에 데이터베이스에서 읽혀 지는데, 이것은 내 맵핑이 어디에서 유래되었지만, 분명히 데이터베이스에 다시 저장하기 위해 무언가를 잃어 버렸습니다.

바라건대 누군가가 올바른 방향으로 나를 가리킬 수 있기를 바랍니다. 이렇게 할 수있는 유일한 방법은 구성 요소를 각 작업 사이에 세션을 별도로 플러시하는 것입니다. 여기

내 매핑은 다음과 같습니다

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

좋아

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, 그래서 내가 일하는 것이 생각했던 내가 말했듯이 기본적으로했다 (그리고 그것) :

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

각 구성 요소를 먼저 저장하고 저장간에 세션을 지우고 지 웁니다. 이것은 세션이 주어 졌기 때문에 필수적이었습니다. 세션은 상태 저장입니다. 더 적절한 해결책은 무국적 세션을 사용하는 것입니다. 나는 어쨌든 그것을 사용할 수 없기 때문에 그 방법을 더 조사하지는 않았지만 주목할 가치가있다.

관련 문제