Fluent Nhibernate - Mapping a list results in NullReferenceException?

别等时光非礼了梦想. 提交于 2020-01-01 19:31:11

问题


I have the following classes and fluent mappings:

  public class A {
    public virtual int Id { get; private set; }
    public virtual string MyString { get; set; }
    public virtual IList<B> MyChildren { get; set; }
 }

  public class B {
    public virtual int Id { get; private set; }
    public virtual DateTime TheDate { get; set; }
  }

  public sealed class AMap : ClassMap<A> {
    public AMap() {
      Id(x => x.Id).GeneratedBy.Native().UnsavedValue(0);
      Map(x => x.MyString);
      HasMany(x => x.MyChildren).AsList(x => x.Column("Ordinal")).KeyColumn("AId").Not.KeyNullable();
    }
  }

  public sealed class BMap : ClassMap<B> {
    public BMap() {
      Id(x => x.Id).GeneratedBy.Native().UnsavedValue(0);
      Map(x => x.TheDate);
    }
  }

This results in the following mapping for A:

  <class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="A" table="`A`">
    <id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="Id" />
      <generator class="native" />
    </id>
    <property name="MyString" type="AnsiString">
      <column name="MyString" length="150" not-null="true" />
    </property>
    <list name="MyChildren" mutable="true">
      <key not-null="true">
        <column name="AId" />
      </key>
      <index>
        <column name="Ordinal" />
      </index>
      <one-to-many class="B" />
    </list>
  </class>

But when I actually try to save an instance of A, I get a NullReferenceException:

System.NullReferenceException : Object reference not set to an instance of an object.
at NHibernate.Collection.PersistentList.GetSnapshot(ICollectionPersister persister)
at NHibernate.Engine.CollectionEntry..ctor(ICollectionPersister persister, IPersistentCollection collection)
at NHibernate.Engine.StatefulPersistenceContext.AddNewCollection(ICollectionPersister persister, IPersistentCollection collection)
at NHibernate.Event.Default.WrapVisitor.ProcessArrayOrNewCollection(Object collection, CollectionType collectionType)
at NHibernate.Event.Default.WrapVisitor.ProcessCollection(Object collection, CollectionType collectionType)
at NHibernate.Event.Default.AbstractVisitor.ProcessValue(Object value, IType type)
at NHibernate.Event.Default.WrapVisitor.ProcessValue(Int32 i, Object[] values, IType[] types)
at NHibernate.Event.Default.AbstractVisitor.ProcessEntityPropertyValues(Object[] values, IType[] types)
at NHibernate.Event.Default.AbstractSaveEventListener.VisitCollectionsBeforeSave(Object entity, Object id, Object[] values, IType[] types, IEventSource source)
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.Save(Object obj)

What am I doing wrong here?

Clarification: This is how I'm using the classes:

var a = new A { MyChildren = new List<B> { new B { TheDate = DateTime.Now } } };
a.MyChildren[0].Parent = a;

session.Save(a);

回答1:


You should add MyChildren = New List<B>(); to your constructor for A




回答2:


Shouldn't your key column be "Id" (as opposed to "AId") for the child collection? I think that this is the source of your problem...




回答3:


I figured this out. The sample above actually does work, but the issue I was trying to reproduce was still running, causing the same error. Sorry about that...

The issue is that we had created this ChildList class, which we returned for the MyChildren property. It simply wrapped the List (or whatever concrete list NHibernate uses for persistent lists), but it took care of setting the Parent property on whatever instance was added or removed from the collection.

Apparently this causes NHibernate problems when saving even a new instance. Returning a normal concrete List works.



来源:https://stackoverflow.com/questions/3417427/fluent-nhibernate-mapping-a-list-results-in-nullreferenceexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!