2009-11-13 7 views
0

Compte tenu des cartes Fluent NHibernate suivantes:Comment puis-je diagnostiquer/réparer cette 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); 
    } 
} 

... et le type d'utilisateur personnalisé donné:

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

Je reçois l'exception suivante et la pile quand je Update Merge le FastTrackPackage avec enfant 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 

Lorsque je Save FastTrackPackage avec un FileHeaderFastTrackRecord je ne reçois aucune erreur et il enregistre correctement. Je peux également Save et Update FileHeaderFastTrackRecords indépendamment.

À ce stade, je suis à perte. Je suspecte le type d'utilisateur personnalisé, mais je ne peux pas être sûr.

Comment puis-je diagnostiquer ou résoudre ce problème?

Répondre

1

Il s'avère que la méthode 'TestPackageUserType.Replace()' était incorrecte. Il renvoyait un caractère quand il retournait un booléen et un code plus bas dans la pile étouffée (fournissant le message d'exception cryptique). Ma nouvelle méthode Replace() ressemble à ceci:

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