Question

Compte tenu des cartes Fluent NHibernate suivantes:

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 pile lorsque I Update Merge le FastTrackPackage avec un 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 

Quand je Save le FastTrackPackage avec un FileHeaderFastTrackRecord je reçois aucune erreur et il enregistre correctement. Je peux aussi Save et Update FileHeaderFastTrackRecords indépendamment.

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

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

Était-ce utile?

La solution

Il se trouve la méthode «TestPackageUserType.Replace () a eu tort. Il revenait char alors qu'il devrait être un retour bool et le code plus bas de la pile étranglée sur elle (la transmission du message cryptique d'exception). Ma nouvelle méthode de Replace() ressemble à ceci:

public object Replace(object original, object target, object owner)
{
  return original;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top