2015-09-30 5 views
0

У меня есть 2 сущности: пользователя и Userprofile, которые имеют двунаправленную @OneToOne отношения между ними.
Из-за какой-то старой конструкции БД UserProfile является владельцем (у меня есть столбец user_id в таблице users_profiles)
Связь Lazy, поскольку у меня есть fetchType Lazy и optional = false.
Все работает так, как ожидалось, я имею в виду, когда загружаю UserProfile, он автоматически не загружает пользователя. Я думаю, это совершенно нормально, поскольку я загружаю со стороны владельца.
Моя проблема заключается в том, что если я загружаю пользователя (принадлежащую ему сторону), он автоматически загружает UserProfile, хотя отношения ленивы.JPA OneToOne Ленивый отношение

Я имею в виду: Является ли это нормальным, когда я загружаю объект из собственной стороны, чтобы загрузить объект владельца?

@Entity 
@Table(name = "users") 
public class User extends BaseEntity implements Serializable { 

    @OneToOne(mappedBy = "user", optional=false, fetch = FetchType.LAZY) 
    private UserProfile profile; 
    // .................rest of entity 
} 




@Entity 
@Table(name="users_profiles") 
public class UserProfile extends BaseEntity implements Serializable { 

    @OneToOne(optional=false, fetch = FetchType.LAZY) 
    @JoinColumn(name="user_id") 
    private User user; 
    // ... rest of entity here 
} 

Способ, которым я проверяю это, путем загрузки объекта User с помощью метода EntityManager find (id).
Я заметил, что когда отношение не ленится, у меня есть только один запрос с объединением внутри. Если я поставлю текущую настройку, у меня есть два отдельных запроса: 1 для пользователя, а другой для профиля.

+1

Вы можете указать тип fetch для каждой стороны отношения. Похоже, вы указали только одно направление, другое направление - поведение по умолчанию. Кроме того, вы можете вставить фрагмент кода JPA, а не объяснять его. –

+0

указано, и он ленив в обоих направлениях. –

+2

http://stackoverflow.com/questions/17987638/hibernate-one-to-one-lazy-loading-optional-false –

ответ

0

Это нормально, по умолчанию, hibernate создает прокси-серверы во время выполнения. Он загружает объекты в качестве прокси-сервера, если не указан режим выборки или не установлен в значение false. Например, , load() всегда извлекает прокси-объекты. Если вы вызываете более одного раза на одном сеансе, он считывает данные из кэша постоянного контекста. Это связано с тем, что, как только объект загружается в кеш, последующие последующие вызовы выполняют повторяемое чтение.

1

Важно понимать, что ленивое поведение загрузки не соблюдается по спецификации JPA, рекомендуется только. Реализация должна быть выполнена, если она поддерживается, и при каких условиях.

Hibernate обычно делает все возможное, чтобы загрузить данные лениво, когда требуется, но в случае one-to-one отображения, когда отношения хранятся в другой таблице (первичный ключ в таблице users_profiles), он должен запросить также второй таблицы для извлечения первичного ключа для создания прокси-объекта. Фактически, он не извлекает только id, а полную строку и создает UserProfile в нетерпении, потому что почти ничего не стоит для получения дополнительных данных, когда таблица должна быть объединена в любом случае.

Ответ на вопрос Hibernate: one-to-one lazy loading, optional = false предполагает, что создание отношений не факультативно должно сделать его ленивым, но я сомневаюсь, что это правда. Спящий режим должен создать прокси-сервер без идентификатора, что, во всяком случае, неверно. Один случай, когда это произойдет, - это когда вы удаляете прокси-объект из коллекции в родительском объекте и затем пытаетесь прочитать его данные - поскольку сам прокси не несет достаточной информации для получения данных лениво, это невозможно без подключения к родительскому объекту организация.

Смежные вопросы