Pergunta

Dados os seguintes mapas fluentes de Nibernate:

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

... e o tipo de usuário personalizado fornecido:

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

Eu recebo a seguinte exceção e pilha quando eu Update Merge O FastTrackPackage com um 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 

Quando eu Save O FastTrackPackage com um FileHeaderFastTrackRecord Não recebo nenhum erro e salva corretamente. Eu também posso Save e Update FileHeaderFastTrackRecords de forma independente.

Neste ponto, estou perdido. Suspeito do tipo de usuário personalizado, mas não tenho certeza.

Como posso diagnosticar ou corrigir esse problema?

Foi útil?

Solução

Acontece que o método 'testpackageUsertype.replace ()' estava errado. Ele estava retornando um char quando deveria retornar um bool e o código mais abaixo na pilha sufocada (fornecendo a mensagem de exceção enigmática). Meu novo Replace() Método se parece com o seguinte:

public object Replace(object original, object target, object owner)
{
  return original;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top