2012-05-17 4 views
4

다 대일 복합 키를 가진 객체를 삭제하려고하면 NHibernate가 던지고 예외가 발생합니다. 개체를 저장하면 제대로 작동합니다. 여기NHibernate KeyNotFoundException on delete

[KeyNotFoundException: The given key was not present in the dictionary.] 
System.ThrowHelper.ThrowKeyNotFoundException() +28 
System.Collections.Generic.Dictionary`2.get_Item(TKey key) +7455516 
NHibernate.Engine.StatefulPersistenceContext.RemoveEntity(EntityKey key) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\StatefulPersistenceContext.cs:434 
NHibernate.Action.EntityDeleteAction.Execute() in d:\CSharp\NH\nhibernate\src\NHibernate\Action\EntityDeleteAction.cs:87 
NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:136 
NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:126 
NHibernate.Engine.ActionQueue.ExecuteActions() in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:174 
NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:241 
NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:19 
NHibernate.Impl.SessionImpl.Flush() in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:1479 

내 도메인 모습입니다 : 다음은 예외입니다 나는 원인이 있었는지 알아 냈

public class OrderClassMap : ClassMap<Order> { 
    public OrderClassMap() { 
     this.Table("Orders"); 
     this.Id(x => x.OrderId).Generated.Identity(); 
     this.Map(x => x.PersistenceId); 
     this.HasMany(x => x.Lines).Inverse().KeyColumn("OrderId").Cascade.AllDeleteOrphan(); 
    } 
} 

public class OrderLineClassMap : ClassMap<OrderLine> { 
    public OrderLineClassMap() { 
     this.Table("OrderLines"); 
     this.CompositeId() 
      .KeyReference(x => x.Order, "OrderId") 
      .KeyProperty(x => x.LineId); 
     this.Map(x => x.PersistenceId); 
    } 
} 

답변

4

:

여기
public class Order : EntityBase { 
    protected Order() {} 
    public Order(Guid persistenceId) : base(persistenceId) { 
     this.Lines = new List<OrderLine>(); 
    } 
    public virtual int OrderId {get; private set;} 
    IList<OrderLine> Lines {get; private set;} 
} 

public class OrderLine : EntityBase { 
    protected OrderLine() {} 
    public OrderLine(Guid persistenceId, Order order, int lineId) : base(persistenceId) { 
     this.Order = order; 
     this.LineId = lineId; 
    } 
    public virtual Order {get; private set;} 
    public virtual LineId {get; private set;} 
} 

public abstart class EntityBase { 
    protected EntityBase() {} 
    protected EntityBase(Guid persistenceId) { 
     this.PersistenceId = persistenceId; 
    } 
    public virtual Guid Persistenceid {get; private set;} 
    public bool IsTransient {get {return Equals(this.PersistenceId, default(Guid)); }} 
    public override bool Equals(object obj) { 
     if(ReferenceEquals(null, obj)) 
      return false; 
     if(ReferenceEquals(this, obj)) 
      return true; 
     if(this.GetType() != obj.GetType()) 
      return false; 
     return this.Equals((IEntity)obj); 
    } 
    public virtual bool Equals(IEntity other) { 
     if(ReferenceEquals(null, other)) 
      return false; 
     if(ReferenceEquals(this, other)) 
      return true; 
     if(this.IsTransient || other.IsTransient) 
      return false; 
     return this.PersistenceId.Equals(other.PersistenceId); 
    } 
    public override int GetHashCode() { 
     return this.IsTransient ? base.GetHashCode() : this.PersistenceId.GetHashCode(); 
    } 
} 

가 내 매핑 파일은 어떻게 생겼는지 오류. 내 엔티티에는 모두 각 엔티티를 고유하게 식별하는 GUID 인 PersistenceId 속성이 있습니다. 내 기본 클래스 인 EntityBase에서 GetHashCode 메서드를 재정 의하여 PersistenceId를 기반으로 해시 코드를 반환합니다. 내가 NHibernate가 예상 한 OrderId를 기반으로 해시 코드를 제공하지 않았기 때문에 이것은 NHibernate에서 잘못되었다. 모든 엔티티에 대해 새로운 GetHashCode 및 Equals 메서드를 구현했으며 삭제가 제대로 작동합니다.

관련 문제