Двунаправленная связь один-к-одному: Hibernate выбирает объекты дважды - PullRequest
2 голосов
/ 29 ноября 2011

У меня есть две сущности, Contract и Customer, между которыми определено двунаправленное отношение один к одному:

В Customer.hbm.xml:

....   
<many-to-one name="contract" class="Contract" fetch="select">
    <column name="CONTRACTID" not-null="true" unique="true" />
</many-to-one>

In Contract.hbm.xml:

...
<one-to-one name="customer" class="Customer" property-ref="contract" />

При переборе по совокупности Customer сущностей (выбираемых в каком-либо запросе HQL) и для каждого customer, обращающегося к полю contract, Hibernate делает два дополнительных оператора для каждого «клиента»:

  1. Ленивая выборка contract, что для меня нормально, так как я собираюсь оптимизировать отложенную выборку с атрибутом batch-size позже.
  2. Снова выборка Customer объекта с SELECT ... FROM Customer WHERE CONTRACTID=?

Как заставить Hibernate использовать экземпляр customer, который уже присутствует в сеансе?

EDIT: Если это невозможно из-за того, что Customer выбирается CONTRACTID вместо первичного ключа Customer в 2.), этот сценарий создает еще одну проблему N + 1, верно?

1 Ответ

0 голосов
/ 30 ноября 2011

Я решил использовать следующий обходной путь:

1) изменив one-to-one in Contract на <set... (один-ко-многим) с lazy="true", access="field" иinverse="false".Свойство с именем customers вместо customer

2) в java-классе Contract Я ввел новое свойство customers, но без новых сеттеров и геттеров (поэтому нам нужен access="field".

3) изменил получатель старого свойства с одним значением, чтобы он возвращал первый элемент набора customers, если и только если он не равен нулю и имеет размер = 1

4) изменил старый установщик, чтобы инициализировать новый HashSet и добавить к нему только customer.

Таким образом, API-интерфейс объекта не изменился, и у меня есть иллюзия, что он отображается как один-к-одному;-).Тем не менее, я был бы признателен за другое решение

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