Nhibernate много-к-одному проблема - PullRequest
1 голос
/ 20 января 2010

У меня проблема с отображением «многие к одному» в следующем коде:

...

<property name ="CustomerID"/>    

<!-- Many-to-one mapping: Customer -->
<many-to-one name="Customer" 
                 class="Customer" 
                 column="CustomerID"
                 insert="false" update="false"/>
<property name="Date" />

...

Вы можете заметить, что я сопоставил два CustomerID с таблицей Customer. Причина, по которой я это делаю, потому что, когда я хочу создать Заказ, я просто присваиваю значение только CustomerID и другим обязательным полям, а затем сохраняю. сопоставление многие-к-одному, я просто хочу получить подробную информацию о каждом идентификаторе клиента.

Но проблема в том, что: после того, как я обновляю customerID Order и Executre SaveOrUpdate с помощью Session.Flush () (я использую HibernateTemplate), я все еще получаю старую фигуру при доступе к Order.Customer. то есть:

Order = getOderByID (1);
Order.CustomerID = 3 // Предположим, значение CustomerId равно 1. Теперь я изменил на 3
SaveOrUpdate (заказ);
Print (Order.Customer.CustomerID) // возвращает 1, что неверно. Должно быть 3

Пожалуйста, помогите ...

Спасибо

Ответы [ 3 ]

3 голосов
/ 21 января 2010

Я бы посоветовал вам взглянуть на эту проблему с точки зрения NHibernate. И не с точки зрения реляционной базы данных. Позвольте мне начать с того, что, по моему мнению, вы должны делать.

var customer = session.Load<Customer>(3);
var order = session.Load<Order>(1);
order.Customer = customer; 

//assuming this is a one directional mapping. otherwise you might 
//have to do some more steps to disassociate the order from the old 
//customers collection and add it to the new customers collection

session.SaveOrUpdate(order);

Теперь order.Customer.CustomerID вернет 3.

Как предположил Серкан, лучше и целесообразнее работать с объектами, а не с первичными ключами.

Кроме того, здесь не должно быть никакого влияния на производительность. Nhibernate может проксировать множество ассоциаций, если у классов есть виртуальные открытые методы. Из-за этого, пока вы запрашиваете только Id клиента, он не будет генерировать отдельный SQL-запрос. Идентификатор уже существует с прокси-объектом.

Что касается исходного вопроса, у меня есть догадка. NHibernate динамически генерирует SQL-запрос на обновление и вставки. Этот случай здесь является обновлением. Вы явно установили для свойства CustomerID значение 3. Но свойство Customer объекта заказа по-прежнему указывает на объект customer с идентификатором 1. Таким образом, когда NHibernate создает запрос sql, он пытается установить значение сначала равным 1, как вы и просили. это к. Затем он также видит, что Customer все еще указывает на старый объект, поэтому установите свойство CustomerId равным 1. Я думаю, что NHibernate путают с двойными сопоставлениями.

Есть две вещи, которые вы можете сделать. Сначала включите свойство show_sql в конфигурации NHibernate.

<nhibernate>
  ...
  <add key="hibernate.show_sql" value="true" />
</nhibernate>

Проверьте, что создается sql при сохранении заказа. Это объяснит вещи лучше.

Во-вторых, после сохранения заказа выполните session.Refresh(order); Вы можете прочитать о методе Refresh () здесь . Это ближе к концу раздела 9.2. Это перезагрузит объект заказа со свежими значениями из базы данных. Вызов order.CustomerID должен показать, какое значение вы сохранили в базе данных.

1 голос
/ 20 января 2010

Я думаю, что в долгосрочной перспективе вы будете чувствовать себя намного счастливее, если попытаетесь забыть об идентификаторах сущностей, как только закончите с отображением ИЛИ. Вы находитесь на другом уровне, который вы должны думать только об объектах. На вашем месте я бы удалил свойство CustomerId все вместе.

Если у вас есть проблемы с производительностью, попробуйте решить их с помощью NHibernate, кэширования и т. Д.

0 голосов
/ 20 января 2010

Две вещи, чтобы попробовать

  1. Сброс сеанса с помощью Session.Dispose, если это NH 2.x, в противном случае используйте Flush()
  2. Назначьте свой идентификатор клиенту.

NHibernate создаст для вас идентификаторы и постарается управлять ими, если вы специально не скажете этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...