2009-11-13 75 views
0

鑑於以下功能NHibernate地圖:如何診斷/修復此NHibernate.PropertyAccessException?

public class FastTrackPackageClassMap : ClassMap<FastTrackPackage> 
{ 
    public FastTrackPackageClassMap() 
    { 
     Id(x => x.Id); 
     References(x => x.UserCreated, "UserIdCreated").Cascade.None(); 
     References(x => x.UserSent, "UserIdSent").Nullable().Cascade.None(); 
     HasMany(x => x.GetFileHeaders()).KeyColumn("PackageId").ForeignKeyConstraintName("PackageId").Cascade.AllDeleteOrphan().Not.LazyLoad().Inverse(); 
     HasMany(x => x.GetEmailRecords()).KeyColumn("PackageId").ForeignKeyConstraintName("PackageId").Cascade.AllDeleteOrphan().Not.LazyLoad().Inverse(); 
     HasMany(x => x.GetPaymentRecords()).KeyColumn("PackageId").ForeignKeyConstraintName("PackageId").Cascade.AllDeleteOrphan().Not.LazyLoad().Inverse(); 
     HasMany(x => x.GetFileTrailers()).KeyColumn("PackageId").ForeignKeyConstraintName("PackageId").Cascade.AllDeleteOrphan().Not.LazyLoad().Inverse(); 
     Map(x => x.TestPackage); 
     Map(x => x.DateTimeCreated).Generated.Insert(); 
     Map(x => x.DateTimeSent).Nullable(); 
    } 
} 

public class FileHeaderFastTrackRecordClassMap : ClassMap<FileHeaderFastTrackRecord> 
{ 
    public FileHeaderFastTrackRecordClassMap() 
    { 
     Id(FileHeaderFastTrackRecord.Expressions.Id); 
     References(x => x.Package, "PackageId"); 
     Map(x => x.FileDateTime); 
     Map(x => x.CustomerId); 
     Map(x => x.TestPackage, "TestIndicator").CustomType(typeof (TestPackageUserType)); 
     Map(x => x.BankId); 
    } 
} 

...和給定的自定義用戶類型:

public class TestPackageUserType : IUserType 
{ 
    public bool Equals(object x, object y) 
    { 
     if (x == null) 
      return false; 
     return x.Equals(y); 
    } 

    public int GetHashCode(object x) { return x.GetHashCode(); } 

    public object NullSafeGet(IDataReader rs, string[] names, object owner) 
    { 
     var testIndicator = (char) NHibernateUtil.Character.NullSafeGet(rs, names[0]); 
     return testIndicator == 'T'; 
    } 

    public void NullSafeSet(IDbCommand cmd, object value, int index) 
    { 
     if (value == null) 
     { 
      NHibernateUtil.Character.NullSafeSet(cmd, null, index); 
      return; 
     } 
     if ((bool) value) { NHibernateUtil.Character.NullSafeSet(cmd, 'T', index); } 
     else { NHibernateUtil.Character.NullSafeSet(cmd, 'P', index); } 
    } 

    public object DeepCopy(object value) 
    { 
     if (value == null) return true; 
     return (bool) value; 
    } 

    public object Replace(object original, object target, object owner) 
    { 
     if (target != null && !(bool) target) 
     { 
      return 'P'; 
     } 
     return 'T'; 
    } 

    public object Assemble(object cached, object owner) { throw new NotImplementedException(); } 

    public object Disassemble(object value) 
    { 
     if (value != null) 
     { 
      var testIndicator = (char[]) value; 
      if (testIndicator[0] == 'P') 
      { 
       return false; 
      } 
     } 
     return true; 
    } 

    public SqlType[] SqlTypes { get { return new[] {new SqlType(DbType.String)}; } } 

    public Type ReturnedType { get { return typeof (bool); } } 

    public bool IsMutable { get; private set; } 
} 

我收到以下異常和堆棧當我 Update Merge的FastTrackPackage用child FileHeaderFastTrackRecord:

NHibernate.PropertyAccessException: Invalid Cast (check your mapping for property type mismatches); setter of BNYM_Extranet.Common.RemEDIFastTrack.FileHeaderFastTrackRecord 

at NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values) 
at NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValues(Object entity, Object[] values) 
at NHibernate.Persister.Entity.AbstractEntityPersister.SetPropertyValues(Object obj, Object[] values, EntityMode entityMode) 
at NHibernate.Event.Default.DefaultMergeEventListener.CopyValues(IEntityPersister persister, Object entity, Object target, ISessionImplementor source, IDictionary copyCache) 
at NHibernate.Event.Default.DefaultMergeEventListener.EntityIsDetached(MergeEvent event, IDictionary copyCache) 
at NHibernate.Event.Default.DefaultMergeEventListener.OnMerge(MergeEvent event, IDictionary copyCache) 
at NHibernate.Impl.SessionImpl.FireMerge(IDictionary copiedAlready, MergeEvent event) 
at NHibernate.Impl.SessionImpl.Merge(String entityName, Object obj, IDictionary copiedAlready) 
at NHibernate.Engine.CascadingAction.MergeCascadingAction.Cascade(IEventSource session, Object child, String entityName, Object anything, Boolean isCascadeDeleteEnabled) 
at NHibernate.Engine.Cascade.CascadeToOne(Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) 
at NHibernate.Engine.Cascade.CascadeAssociation(Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) 
at NHibernate.Engine.Cascade.CascadeProperty(Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) 
at NHibernate.Engine.Cascade.CascadeCollectionElements(Object child, CollectionType collectionType, CascadeStyle style, IType elemType, Object anything, Boolean isCascadeDeleteEnabled) 
at NHibernate.Engine.Cascade.CascadeCollection(Object child, CascadeStyle style, Object anything, CollectionType type) 
at NHibernate.Engine.Cascade.CascadeAssociation(Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) 
at NHibernate.Engine.Cascade.CascadeProperty(Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) 
at NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything) 
at NHibernate.Event.Default.DefaultMergeEventListener.CascadeOnMerge(IEventSource source, IEntityPersister persister, Object entity, IDictionary copyCache) 
at NHibernate.Event.Default.DefaultMergeEventListener.EntityIsDetached(MergeEvent event, IDictionary copyCache) 
at NHibernate.Event.Default.DefaultMergeEventListener.OnMerge(MergeEvent event, IDictionary copyCache) 
at NHibernate.Event.Default.DefaultMergeEventListener.OnMerge(MergeEvent event) 
at NHibernate.Impl.SessionImpl.FireMerge(MergeEvent event) 
at NHibernate.Impl.SessionImpl.Merge(String entityName, Object obj) 
at NHibernate.Impl.SessionImpl.Merge(Object obj) 
at DAL.NHibernate.RepositoryWithTypedId`2.Update(T entity) in Repository.cs: line 72 
at UnitTests.DAL.NHibernate.RemEDIFastTrack.FastTrackPackageRepositoryFixture.Update() in FastTrackPackageRepositoryFixture.cs: line 290 

當我使用FileHeaderFastTrackRecord的FastTrackPackage時,我收到了沒有錯誤,並保存正確。我也可以獨立地SaveUpdate FileHeaderFastTrackRecords。

在這一點上,我不知所措。我懷疑自定義用戶類型,但我無法確定。

如何診斷或修復此問題?

回答

1

原來'TestPackageUserType.Replace()'方法是錯誤的。當它應該返回一個char類型時,它會返回一個char類型的字符串,並將代碼放在堆棧上進行窒息(提供神祕的異常消息)。我的新Replace()方法如下所示:

public object Replace(object original, object target, object owner) 
{ 
    return original; 
}