0

I am getting error not-null property references a null or transient value in many to one relation in NHibernate.

Code:

class MyData
{
    public string Name{get;set;}    
    public virtual UploadData UploadData { get; set; }
    public int UploadId{get;set;}
}

class UploadData
{
    public int UploadId{get;set;}
    public DateTime Date{get;set;}
}

Mappings

<class name="MyData, NS" table="MyData" lazy="false">
    <id name="Identifier" type="Int32" unsaved-value="0">
      <column name="Identifier" sql-type="int" 
              not-null="true" unique="true" index="PK_dbo.MyData"/>
      <generator class="identity" />
    </id>
    <property name='Name' column='Name'/>
    <property name='UploadId' column='UploadId'/>      
    <many-to-one name="UploadData" class="UploadData, NS">
          <column name="UploadId" length="5" sql-type="int" not-null="true" index="UploadId"/>
    </many-to-one>
 </class>

UploadData class

<class name="UploadData, NS" table="UploadData" lazy="false">
    <id name="UploadId" type="Int32" unsaved-value="0">
      <column name="UploadId" sql-type="int" 
              not-null="true" unique="true" index="PK_dbo.UploadData"/>
      <generator class="identity" />
    </id>
    <property name='Data' column='Date' />
</class>

I am deleting records using below code.

foreach(MyData obj in myDataCollection)
repo.Delete(obj) // delete using repository.
repo.Delete(obj.UploadData) 

If myDataCollection contains 2 instances which have same UploadData then I will get the error "not-null property references a null or transient value" on repo.Delete(obj)

I googled the issue and found solutions (e.g. make not-null="false" in mappings) but didn't solve the issue.

Marijn
  • 10,367
  • 5
  • 59
  • 80
meetjaydeep
  • 1,752
  • 4
  • 25
  • 39
  • I think you're missing a cascade. I'm really bad with the Xml mappings, but iirc you want an inverse cascade on the parent and a regular cascade on the child. http://www.jroller.com/RickHigh/entry/hibernate_hibernate_not_null_property – cloggins Jun 11 '12 at 12:54

1 Answers1

1

Specify cascade="all" then the delete operation is cascaded and NHibernate should take care of duplicate references.

<many-to-one name="UploadData" class="UploadData, NS" cascade="all">

// then this is enough to delete mydata and associated UploadData
foreach(MyData obj in myDataCollection)
{
   repo.Delete(obj);
}

I also see several problems here

  • public int UploadId{ get; set; } is redundant and will result in SQL parameter errors because the column is mapped twice. UploadData.UploadId will give the same
  • length="5" is ignored because it is only relevant for string columns
rineez
  • 753
  • 13
  • 33
Firo
  • 30,626
  • 4
  • 55
  • 94
  • I got below error Spring.Data.NHibernate.HibernateObjectRetrievalFailureException: Spring.Data.NHibernate.HibernateObjectRetrievalFailureException: deleted object would be re-saved by cascade (remove deleted object from associations)[UploadData] ---> NHibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations)[UploadData]. – meetjaydeep Jun 11 '12 at 13:13
  • i tested this with a minimal example and theres only a problem when you do not delete all objects referencing the Uploaddata (or set the refernces to null) i suspect you have different problem somewhere – Firo Nov 01 '12 at 06:39