English 中文(简体)
How can I diagnose/fix this NHibernate.PropertyAccessException?
原标题:

Given the following Fluent NHibernate maps:

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

... and the given custom user type:

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

I receive the following exception and stack when I Update Merge the FastTrackPackage with a 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 

When I Save the FastTrackPackage with a FileHeaderFastTrackRecord I receive no error and it saves properly. I can also Save and Update FileHeaderFastTrackRecords independently.

At this point I m at a loss. I suspect the custom user type, but I can t be sure.

How can I diagnose or fix this problem?

最佳回答

It turns out the TestPackageUserType.Replace() method was wrong. It was returning a char when it should be returning a bool and code further down the stack choked on it (providing the cryptic exception message). My new Replace() method looks like this:

public object Replace(object original, object target, object owner)
{
  return original;
}
问题回答

暂无回答




相关问题
nHibernate one-to-many inserts but doesnt update

Instead of getting into code, I have a simple question. Default behavior for a simple one-to-many is that it inserts the child record then updates the foreign key column with the parent key. Has ...

How Do I copy an existing nhibernate object as a new object?

I a persisted NHibernate object that I would like to repersist as a new entity. How do I get NHibernate to save this object as if it was a new? I am thinking I might create a session interceptor to ...

join across databases with nhibernate

I am trying to join two tables that reside in two different databases. Every time, I try to join I get the following error: An association from the table xxx refers to an unmapped class. If the ...

WPF - MVVM - NHibernate Validation

Im facing a bit of an issue when trying to validate a decimal property on domain object which is bound to a textbox on the view through the viewmodel. I am using NHibernate to decorate my property on ...

NHibernate Search in a List using ICriteria

I have my class X : public class ClassX { public virtual IList<ClassY> ListY { get; set; } ... } My ClassX mapping (using Fluent) ... HasMany<ClassX>(x => x.ListY ) ....

热门标签