2015-10-09 2 views
0

У меня есть вопрос, связанный с ленивой загрузкой ассоциации ассоциаций OneToOne.Ленивая проблема при загрузке с одним соединением в спящем режиме

Случай 1 внешнего ключа в дочерней таблице (адрес)

@Entity 
public class User { 
    .......... 
    @OneToOne(mappedBy="user") 
    private Address address; 


@Entity 
public class Address{ 
    ......... 
    @OneToOne 
    @JoinColumn(name = "user_id") 
    private User user; 

В вышеприведенном Адрес ленивая загрузка не работает.

Случай 2 внешнего ключа в родительской таблице (Пользователь)

@Entity 
public class User { 
    ............. 
    @OneToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name="address_id") 
    private Address address; 


@Entity 
public class Address { 
    ........ 
    @OneToOne(mappedBy="address") 
    private User user; 

В вышеуказанному адресу ленивых погрузочных работ.

Может ли кто-нибудь объяснить мне, почему One to one ленивая загрузка не работает в первом случае, но работает во втором?

+0

Что вы подразумеваете под цитатой: «ленивая загрузка не работает»? – WeMakeSoftware

+0

Это означает, что только для пользователя, адрес не должен быть выбран – Anand

ответ

2

@OneToOne несколько сложнее в обращении.

Все зависит от того, какой провайдер постоянства вы используете.

Некоторые поставщики услуг не уважают FetchType.LAZY Подсказка.

Вы можете попробовать указать (на обоих концах связи)

@OneToOne(optional = true, fetch = FetchType.LAZY) 

Чтобы понять, что здесь происходит давайте посмотрим на уровне:

первый случай:

+-----------------+    +------------------+ 
| USER   |    | Address   | 
|     |1   1|     | 
|     +-------------+ USER_ID (FK) | 
|     |    |     | 
|     |    |     | 
+-----------------+    +------------------+ 

Когда вы загружаете пользователя, Hibernate должен знать, присутствует ли адрес или нет.

Так Hibernate выдает запрос SQL похож на это:

SELECT * FROM USER WHERE ID = ? 
SELECT * FROM ADDRESS WHERE user_id = ? 

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

Второй случай:

+-----------------+    +------------------+ 
| USER   |    | Address   | 
|     |1   1|     | 
| ADDRESS_ID  +-------------+     | 
|     |    |     | 
|     |    |     | 
+-----------------+    +------------------+ 

SELECT * FROM USER WHERE ID = ? 

Hibernate не нужно проверить, если адрес или нет. Вот почему создается прокси-сервер.

+0

Не могли бы вы объяснить мне разницу между двумя случаями? – Anand

+0

обновил ответ – WeMakeSoftware

0

Прочтите эту статью. Это даст вам понять, почему один на один по обратному боковому (отображаемому) атрибуту не работает должным образом. One to One Lazy explanation.

Фактически на обратной стороне hibernate необходимо знать, каково значение отображения, потому что пользователь может запросить значение немедленно.

Прочтите статью, и вы получите четкое представление о том, как все работает.

Благодаря

0

я не смог заставить его работать, так что я завелся, используя подготовленное заявление, в котором я JOIN FETCH то, что Hibernate был запрашивая после-фактум, так или иначе.

Добавление optional=true или фальсификация отношений OneToMany, IMO, неправильные способы исправить это.