20

tôi nhận được ngoại lệ này (Full ngoại lệ ở phía dưới):NHibernate - bất động sản không null tham chiếu đến một giá trị null hay thoáng

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" 

tôi đã thực hiện rất nhiều Googling và nó có vẻ phổ biến nhất gây ra cho rằng lỗi là khi một hiệp hội là bi-directional nhưng chỉ có một nửa đã được thiết lập. Như trong: Bảo hiểm.Patient = Bệnh nhân được gọi nhưng Bệnh nhân. Bảo hiểm.Thêm (Bảo hiểm) thì không. Tôi, trên thực tế, có một kịch bản như thế nhưng tôi đã kiểm tra các đối tượng ngay trước khi gọi Lưu với nó và cả Insurance.Patient và Patient.Insurances [0] là đúng đối tượng.

Khả năng khác mà ngoại lệ này dường như để tham khảo là một giá trị thoáng . Trong trường hợp của tôi mọi đối tượng là thoáng qua vì vậy tôi nghi ngờ nguồn gốc của vấn đề của tôi là ở đây. Tuy nhiên, mọi thứ cần để tạm thời ngay bây giờ vì chưa có gì được lưu. Tôi sẽ mong NHibernate tồn tại những thứ thay vì than phiền rằng họ là không được duy trì.

Dưới đây là một số đoạn từ ánh xạ của tôi (thông thạo):

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

      ... 
     } 

Vì vậy, những gì có thể vấn đề này?


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: 
+0

bạn có thể post đoạn code gây ra ngoại lệ được ném ra. –

+0

Mã là bệnh nhân = Session.SaveOrUpdateCopy (bệnh nhân); Tôi nghĩ rằng bất kỳ phương pháp ISession.Save nào nó mặc dù. – brendanjerwin

Trả lời

16

Một khả năng khác là bạn đang lưu toàn bộ biểu đồ đối tượng và biểu đồ đó là hình tròn và các mục không thể rỗng. Bạn có thể cho NHibernate không có trật tự hợp pháp để thực hiện việc chèn. (Nó sẽ tạo ra một thông báo lỗi tốt hơn, nhưng nó tạo ra cái này).

Nếu không nhìn thấy phần còn lại của nguồn, thật khó để được trợ giúp thêm. Hãy thử xóa các thực thể khỏi ánh xạ (và không lưu chúng) cho đến khi bạn có thể tìm ra nguyên nhân gây ra sự cố.

+1

Có, chính xác, lưu toàn bộ biểu đồ, đó là hình tròn và các mục không thể rỗng. Cách duy nhất để duy trì nó là chèn một số phần của thực thể, chèn một số thực thể khác và sau đó quay trở lại với các bản cập nhật xung quanh để kết nối chúng. NH không thể mò mẫm quá trình đó sao? – brendanjerwin

+0

Không. Nếu các mục không thể rỗng, không có cách nào để thực hiện chèn đầu tiên! NH không báo cáo một lỗi rất tốt đẹp mặc dù. –

+3

Nếu bạn đặt Cascade thành All() hoặc SaveUpdate() trên ánh xạ bệnh nhân của bạn thì điều này sẽ hoạt động theo gợi ý của Sid, bên dưới. –

0

Dường như ngoại lệ bắt nguồn tại dòng 25 của file RepositoryBase.cs của bạn, có lẽ khi Save() được gọi trên một trong những đối tượng thoáng qua của bạn. Cái nào đang được lưu?

Ngoài ra, và nó có thể không liên quan vì tôi không quen thuộc với cú pháp Fluent, nên đối tượng con (bảo hiểm trong trường hợp này) có .Cascade.Tất cả vào nó? Trong cú pháp lược đồ XML tiêu chuẩn, chỉ ánh xạ cha có cascade = "all" trên tập hợp các đối tượng con.

+0

Đối tượng bệnh nhân đang được lưu. Ý bạn là gì bởi "cha mẹ" RE: Cascade = all? Bên sở hữu mối quan hệ (bảo hiểm) hoặc chủ sở hữu của thực thể kia (bệnh nhân)? – brendanjerwin

+0

BTW, tôi đã dừng việc ném ngoại lệ bằng cách lưu bệnh nhân trước khi tạo các đối tượng bảo hiểm. Bằng cách đó, Insurance.Patient không tham chiếu đến một đối tượng tạm thời. Tuy nhiên, điều đó có vẻ sai với tôi. NH không nên có thể tồn tại một đồ thị toàn bộ đối tượng và biết để tồn tại các obj thoáng qua? – brendanjerwin

8

Tôi đã gặp sự cố này gần đây và nó phải liên quan đến cách các mối quan hệ hai chiều NHibernate được duy trì. Bạn có bản đồ chính xác và do đó NHibernate sẽ thực hiện chèn bệnh nhân không có vấn đề. Sau đó NHibernate cần phải lấy chìa khóa từ bệnh nhân và cascade mà vào bảo hiểm. Vì Bệnh nhân chưa tồn tại, các khóa không tồn tại và không thể thực hiện lần chèn thứ hai. Điều quan trọng là để thiết lập các mối quan hệ thông qua mã trước khi kiên trì, một cái gì đó như thế này:

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

Bây giờ nó là ngoại với tôi rằng bạn phải thiết lập thuộc tính Bệnh nhân vào mục bộ sưu tập, nhưng nếu bạn bỏ qua sự kiên trì tất cả cùng nhau bạn sẽ cài đặt mã này độc lập với chiến lược kiên trì của mình.

9

không chắc chắn nếu nó giúp nhưng điều này đã làm cho tôi.

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

thác = "tất cả" là những gì tôi bỏ lỡ trước

+1

Cảm ơn, nó đã làm việc cho tôi. –

+0

Tôi đang sử dụng Entity Developer để tạo ánh xạ và đặt thuộc tính Cascade trên thực thể liên quan là vấn đề đối với tôi – hanzolo

1

này đã làm việc cho tôi. Những điều quan trọng ở đây là chúng ta có References với Cascade.All() và chúng tôi không có Inverse() trên HasMany

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

    ... 
} 

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

    ... 
} 
Các vấn đề liên quan