views:

297

answers:

1

While trying to create a Bi-directional one-to-one mapping in NHibernate, I found that, I am unable to have the Reference of the objects recursively.

For example: suppose I have one-to-one relationships between Person and Address.

then after executing the following code,

class Person
{
    ... ...
    public Address Address { get;set; }
}

class Address
{
    ... ...
    public Person Person {get;set;}
}

Repository<Person> rep = new Repository<Person>();
Person p = rep.Get<Person>(1);

I need to have a non-null value from p.Address.Person. I.e. the same person with an ID of 1.

But the property is returning a null-value.

What should I look for to solve the problem?

My database tables are like this:

Address {ID, Desc}
Person {ID, Name, AddressID}

Person.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping
    xmlns="urn:nhibernate-mapping-2.2"
     default-access="property"
    >
  <class name="NHibernate__BiDirectional__One_To_One.BO.Person, NHibernate__BiDirectional__One_To_One.BO" 
         table="Person">
    <id name="ID">
      <generator class="native" />
    </id>
    <property name="Name"/>

    <many-to-one
        name="Address"
        class="NHibernate__BiDirectional__One_To_One.BO.Address, NHibernate__BiDirectional__One_To_One.BO"
        column="AddressID" 
        cascade="all" 
        unique="true" />

  </class>
</hibernate-mapping>

Address.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping
  xmlns="urn:nhibernate-mapping-2.2"
   default-access="property"
  >
  <class name="NHibernate__BiDirectional__One_To_One.BO.Address, NHibernate__BiDirectional__One_To_One.BO" 
         table="Address">
    <id name="ID" >
      <generator class="native" />
    </id>
    <property name="Desc"/>      
    <one-to-one
        name="Person"
        class="NHibernate__BiDirectional__One_To_One.BO.Person, NHibernate__BiDirectional__One_To_One.BO"
        />
  </class>
</hibernate-mapping>

I am also getting an error:

could not load an entity: [NHibernate__BiDirectional__One_To_One.BO.Person#1][SQ
L: SELECT person0_.ID as ID0_1_, person0_.Name as Name0_1_, address1_.ID as ID1_
0_, address1_.Desc as Desc1_0_, address1_.AddressID as AddressID1_0_ FROM Person
 person0_ left outer join Address address1_ on person0_.ID=address1_.AddressID W
HERE person0_.ID=?]
Incorrect syntax near the keyword 'Desc'.
A: 

There are two varieties of one-to-one association:

• primary key associations

• unique foreign key associations

Primary key associations don't need an extra table column; if two rows are related by the association then the two table rows share the same primary key value. So if you want two objects to be related by a primary key association, you must make sure that they are assigned the same identifier value! For a primary key association, add the following mappings to Employee and Person, respectively.

<one-to-one name="Person" class="Person"/>
<one-to-one name="Employee" class="Employee" constrained="true"/>

Now we must ensure that the primary keys of related rows in the PERSON and EMPLOYEE tables are equal.

We use a special NHibernate identifier generation strategy called foreign:

<class name="Person" table="PERSON">
<id name="Id" column="PERSON_ID">
<generator class="foreign">
<param name="property">Employee</param>
</generator>
</id>
...
<one-to-one name="Employee"
class="Employee"
constrained="true"/>
</class>

A newly saved instance of Person is then assigned the same primar key value as the Employee instance refered with the Employee property of that Person. Alternatively, a foreign key with a unique constraint, from Employee to Person, may be expressed as:

<many-to-one name="Person" class="Person" column="PERSON_ID" unique="true"/>

And this association may be made bidirectional by adding the following to the Person mapping:

<one-to-one name="Employee" class="Employee" property-ref="Person"/>

Have a look at this

https://forum.hibernate.org/viewtopic.php?p=2362617&amp;sid=23c4df33b683409df9b5d844037d6d03

David
I am confused. Can u plz provide me with the db table columns?
JMSA
@JMSA Can you tell how your 2 tables for PERSON and ADDRESS relate? i.e. have you put the PERSON table primary key in the ADDRESS table or are you using the same primary key for both tables?
David
I have the tables, Address {ID, Desc} and Person {ID, Name, AddressID}.I.e. AddressID is an FK in Person-table.
JMSA
@JMSA Have a look at the link I`ve added to the answer.
David