c# - NHibernate-not-null-Eigenschaft verweist auf einen Null- oder Transientenwert



exception fluent-nhibernate (4)

Das hat für mich funktioniert. Die wichtigen Dinge hier sind, dass wir References mit Cascade.All() und wir nicht Inverse() auf HasMany

public PatientMap()
{
    HasMany(x => x.Insurances)
        .WithKeyColumn("uid_Patient")
        .Cascade.All();

    ...
}

public InsuranceMap()
{
    References(x => x.Patient, "uid_Patient")
        .Not.Nullable()
        .Cascade.All();

    ...
}

https://ffff65535.com

Ich erhalte diese Ausnahme (Vollständige Ausnahme unten):

NHibernate.PropertyValueException was unhandled by user code
 Message="not-null property references a null or transient
valueClearwave.Models.Encounters.Insurance.Patient"
 Source="NHibernate"
 EntityName="Clearwave.Models.Encounters.Insurance"
 PropertyName="Patient"

Ich habe viel gegoogelt und es scheint die häufigste Ursache für diesen Fehler zu sein, wenn eine Assoziation bidirektional ist, aber nur eine Hälfte gesetzt wurde. Wie in: Insurance.Patient = Patient wird angerufen, aber Patient.Insurances.Add (Insurance) ist nicht. Ich habe tatsächlich ein solches Szenario, aber ich habe das Objekt kurz vor dem Aufruf von Speichern überprüft, und sowohl Insurance.Patient als auch Patient.Insurances [0] sind die richtigen Objekte.

Die andere Möglichkeit, auf die diese Ausnahme zu verweisen scheint, ist ein Übergangswert. In meinem Fall ist jedes Objekt vorübergehend, also vermute ich, dass die Wurzel meines Problems hier ist. Im Moment muss jedoch alles vorübergehend sein, da noch nichts gespeichert wurde. Ich würde erwarten, dass NHibernate die Dinge beharrt, anstatt sich zu beschweren, dass sie nicht bestehen bleiben.

Hier sind einige Schnipsel von meinen Mappings (fließend):

       public PatientMap()
       {
           WithTable("tPatient");

           Id(x => x.Id, "uid_Patient").GeneratedBy.GuidComb
().Access.AsReadOnlyPropertyThroughCamelCaseField();

           HasMany(x => x.Insurances).WithKeyColumn("uid_Patient")
               .Cascade.All()
               .Inverse();

          ...
       }

      public InsuranceMap()
       {
           WithTable("tPatientInsuranceInfo");

           Id(x => x.Id,
"uid_PatientInsuranceInfo").GeneratedBy.GuidComb
().Access.AsReadOnlyPropertyThroughCamelCaseField();

           References(x => x.Patient, "uid_Patient").Not.Nullable
().Cascade.All();

           ...
        }

Also, was könnte das Problem sein?

NHibernate.PropertyValueException was unhandled by user code
 Message="not-null property references a null or transient
valueClearwave.Models.Encounters.Insurance.Patient"
 Source="NHibernate"
 EntityName="Clearwave.Models.Encounters.Insurance"
 PropertyName="Patient"
 StackTrace:
      at NHibernate.Engine.Nullability.CheckNullability(Object[]
values, IEntityPersister persister, Boolean isUpdate)
      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.DefaultMergeEventListener.EntityIsTransient
(MergeEvent event, IDictionary copyCache)
      at NHibernate.Event.Default.DefaultMergeEventListener.OnMerge
(MergeEvent event, IDictionary copyCache)
      at NHibernate.Impl.SessionImpl.FireSaveOrUpdateCopy(IDictionary
copiedAlready, MergeEvent event)
      at NHibernate.Impl.SessionImpl.SaveOrUpdateCopy(String
entityName, Object obj, IDictionary copiedAlready)
      at
NHibernate.Engine.CascadingAction.SaveUpdateCopyCascadingAction.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.CascadeOn(IEntityPersister
persister, Object parent, Object anything)
      at
NHibernate.Event.Default.AbstractSaveEventListener.CascadeBeforeSave
(IEventSource source, IEntityPersister persister, Object entity,
Object anything)
      at
NHibernate.Event.Default.DefaultMergeEventListener.EntityIsTransient
(MergeEvent event, IDictionary copyCache)
      at NHibernate.Event.Default.DefaultMergeEventListener.OnMerge
(MergeEvent event, IDictionary copyCache)
      at NHibernate.Impl.SessionImpl.FireSaveOrUpdateCopy(IDictionary
copiedAlready, MergeEvent event)
      at NHibernate.Impl.SessionImpl.SaveOrUpdateCopy(String
entityName, Object obj, IDictionary copiedAlready)
      at
NHibernate.Engine.CascadingAction.SaveUpdateCopyCascadingAction.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.CascadeOn(IEntityPersister
persister, Object parent, Object anything)
      at
NHibernate.Event.Default.AbstractSaveEventListener.CascadeBeforeSave
(IEventSource source, IEntityPersister persister, Object entity,
Object anything)
      at
NHibernate.Event.Default.DefaultMergeEventListener.EntityIsTransient
(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.FireSaveOrUpdateCopy(MergeEvent
event)
      at NHibernate.Impl.SessionImpl.SaveOrUpdateCopy(Object obj)
      at Clearwave.Models.Data.Util.RepositoryBase`2.Save(EntityType&
entity) in C:\Projects\ClearWave\Src\Common\Domain Models
\Clearwave.Models.Data-NHibernate\Util\RepositoryBase.cs:line 25
      at IntegrationWebServices.FromMirth.SubmitMessage(Message
theMessage, Guid providerOrganizationId)
      at SyncInvokeSubmitMessage(Object , Object[] , Object[] )
      at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke
(Object instance, Object[] inputs, Object[]& outputs)
      at
System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin
(MessageRpc& rpc)
 InnerException:

Eine andere Möglichkeit besteht darin, dass Sie ein gesamtes Objektdiagramm speichern und dieses Diagramm zirkulär ist und Elemente nicht null sein können. Sie könnten NHibernate keine rechtliche Reihenfolge geben, in der die Inserts ausgeführt werden. (Es sollte eine bessere Fehlermeldung erzeugen, aber es erzeugt diese).

Ohne den Rest der Quelle zu sehen, ist es schwer, mehr zu helfen. Versuchen Sie, Entitäten aus den Zuordnungen zu entfernen (und nicht zu speichern), bis Sie herausfinden können, was das Problem verursacht.


Ich hatte dieses Problem in letzter Zeit und es hat damit zu tun, wie die bidirektionalen Beziehungen von NHibernate beibehalten werden. Sie haben das Mapping korrekt und deshalb wird NHIbernate den Patienten einfügen kein Problem. Dann muss NHibernate den Schlüssel von Patienten übernehmen und in Versicherungen eingliedern. Da der Patient noch nicht existiert, sind die Schlüssel nicht vorhanden und der zweite Einsatz kann nicht durchgeführt werden. Der Schlüssel besteht darin, die Beziehung über den Code vor der Persistenz festzulegen, etwa so:

patient = new Patient();
patient.Insurances.Add( new Insurance{ Patient = patient } );
repository.Save( patient);

Jetzt war es mir fremd, dass Sie die Eigenschaft "Patient" auf den Sammlungsgegenstand setzen müssen, aber wenn Sie Persistenz alle zusammen ignorieren, werden Sie dies unabhängig von Ihrer Persistenzstrategie im Code einstellen.


nicht sicher, ob es hilft, aber das hat es für mich getan.

<many-to-one name="Company" column="CompanyId" cascade="all" not-null="true"/>

cascade = "all" war was ich vorher verpasst habe





nhibernate-mapping