Двунаправленная картографическая проблема NHibernate - PullRequest
4 голосов
/ 29 января 2010

Пытаясь создать двунаправленное сопоставление один-к-одному в NHibernate, я обнаружил, что не могу рекурсивно получить ссылку на объекты.

Например: предположим, у меня есть отношения один-к-одному между Person и Address.

затем после выполнения следующего кода

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

Мне нужно не-1010 * значение от p.Address.Person. То есть тот же человек с идентификатором 1.

Но свойство возвращает null -значение.

Что я должен искать, чтобы решить проблему?

Мои таблицы базы данных выглядят так:

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>

Я также получаю сообщение об ошибке:

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'.

1 Ответ

8 голосов
/ 29 января 2010

Существует два варианта взаимно-однозначного объединения:

• ассоциации первичных ключей

• ассоциации уникальных внешних ключей

Связи первичных ключей не нуждаются в дополнительном столбце таблицы; если две строки связаны ассоциацией, то две строки таблицы имеют одинаковое значение первичного ключа. Поэтому, если вы хотите, чтобы два объекта были связаны первичным ключом, Вы должны убедиться, что им присвоено одинаковое значение идентификатора! Для связи первичного ключа добавьте следующие сопоставления для Employee и Person соответственно.

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

Теперь мы должны убедиться, что первичные ключи связанных строк в таблицах PERSON и EMPLOYEE равны.

Мы используем специальную стратегию создания идентификаторов NHibernate, которая называется 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>

Вновь сохраненному экземпляру Person присваивается то же значение первичного ключа, что и для экземпляра Employee, на который ссылаются с собственностью Сотрудника этого лица. В качестве альтернативы внешний ключ с уникальным ограничением, от Сотрудника до Человека, может быть выражен как:

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

И эту ассоциацию можно сделать двунаправленной, добавив следующее в отображение Персона :

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

Посмотрите на это

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

...