代码之家  ›  专栏  ›  技术社区  ›  ddc0660

如何诊断/修复此nhibernate.propertyaccessexception?

  •  0
  • ddc0660  · 技术社区  · 15 年前

    考虑到以下流畅的NHibernate地图:

    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:

    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 
    

    当我 Save 带有fileheaderfasttrackrecord的fasttrackpackage没有收到错误,它正确保存。我也可以 保存 更新 独立文件头fasttrackrecords。

    在这一点上,我很茫然。我怀疑自定义用户类型,但我不能确定。

    如何诊断或修复此问题?

    1 回复  |  直到 15 年前
        1
  •  1
  •   ddc0660    15 年前

    结果发现“testpackageUserType.replace()”方法错误。它返回了一个字符,这时它应该返回一个bool,并在阻塞的堆栈下面进一步编码(提供神秘的异常消息)。我的新 Replace() 方法如下:

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