powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate. N+1. Best practice
14 сообщений из 14, страница 1 из 1
Hibernate. N+1. Best practice
    #37636429
Помогите разобраться. Разбираюсь с Hibernate, стало интересно вот что.
Прочитал тут про проблему n+1. Что если у нас есть вложенная сущность, то происходит минимум 2 запроса к БД, вместо одного.
Прочитал также про пути решения:
1. @Fetch
2. FetchMode.EAGER
3. @Batch

Но что делать, если в одном участке программы мне нужна Lazy загрузка объекта, а в другом полная?
Какие есть пути решения? Может быть есть какой-то специальный паттерн проектирования для этого? Как это реализовать? Буду благодарен за простой пример или ссылку на него.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37636431
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Junior Java Developer ,
Если нужна Lazy - делаете Lazy. Если нужна полная - делаете HQL запрос с FETCH JOIN.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37636433
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Junior Java Developer,
нечётко сформулировал проблему.
- какая разница сколько запросов? Имеет значение только при оптимизации.
- есть проблема с Lazy.

Но, сабж про исключения на отложенной загрузке , продиктован только 1) внимательностью при программировании и 2) отсутствием механизмов автоматизации ТОЛЬКО этого вопроса.
1 - это, никакая IDE не поймёт сама, какие поля надо метить как LAZY
2 - это, каждый "догружает" объекты в ГУИ сам своим способом.
Бери себе самый простой - ГРУЗИ ВСЁ СРАЗУ, если обратного не требует ТЗ.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37636434
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
мммм.
Даже не в этом проблема :)
Хибер аккуратно и умно всё делает с LAZY. При первом обращении к полю - он догружает объекты.
Проблема в том, что он закрывает соединение с БД слишком быстро. А потом ничего не помнит - память короткая :)
Поэтому, если надо не загруженный объект, а соединение с БД закрыто - будет исключение.
Парадокс.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37636435
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123- какая разница сколько запросов? Имеет значение только при оптимизации.

Это не оптимизация. Это просто здравый смысл.

Petro123- есть проблема с Lazy.

Проблема с lazy заканчивается ровно тогда, когда разбираешься с ленивой загрузкой.

Petro123Бери себе самый простой - ГРУЗИ ВСЁ СРАЗУ, если обратного не требует ТЗ.
Да-да, а потом говорят, что hibernate - тормозящая гадость.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37636440
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Junior Java Developer,
нечётко сформулировал проблему.
- какая разница сколько запросов? Имеет значение только при оптимизации.
- есть проблема с Lazy.

Но, сабж про исключения на отложенной загрузке , продиктован только 1) внимательностью при программировании и 2) отсутствием механизмов автоматизации ТОЛЬКО этого вопроса.
1 - это, никакая IDE не поймёт сама, какие поля надо метить как LAZY
2 - это, каждый "догружает" объекты в ГУИ сам своим способом.
Бери себе самый простой - ГРУЗИ ВСЁ СРАЗУ, если обратного не требует ТЗ.
Petro123мммм.
Даже не в этом проблема :)
Хибер аккуратно и умно всё делает с LAZY. При первом обращении к полю - он догружает объекты.
Проблема в том, что он закрывает соединение с БД слишком быстро. А потом ничего не помнит - память короткая :)
Поэтому, если надо не загруженный объект, а соединение с БД закрыто - будет исключение.
Парадокс.Вынужден констатировать, что вы абсолютно не поняли вопроса автора. Речь идет про N+1 проблему и про то, как эффективно реализовывать разные стратегии загрузки графов объектов.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37636442
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svenom,
дык я и сказал, что не понял проблему. :)
Вынужден констатировать, что много букффф вместо проблемы.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37637468
Извиняюсь, если я не ясно сформулировал вопрос. Вопрос был такой относительно вложенных сущностей. есть 2 стратегии: Lazy и не-Lazy. Как быть, когда в программе требуется оба подхода? То, что если отказаться от Lazy все будет работать без ошибок, я прекрасно понимаю.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37637472
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Junior Java Developer,

Я когда делал небольшой проект на hibernate, почти все ассоациации пометил как lazy и при необходимости просто писал нужный мне HQL. В результате вместо страшного количества запросов (на используемых данных вроде 20 было, а то и тридцать) получил 1 запрос.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37637550
igorolv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Следует иметь в виду, что fetch join в hql транслируется в left join в sql. Поэтому если использовать fetch join для загрузки нескольких ассоциаций к одному объекту сразу - можно получить выборку декартового произведения нескольких таблиц.

Например, предположим есть объект "Работник" с detail-ами "Отпуска", "Параметры расчета зарплаты", "Выплаты". Пусть у 1 работника есть 10 отпусков, 5 параметров расчета и 120 выплат. Тогда запрос "select * from Работник fetch join Работник.Отпуска fetch join Работник.Параметры fetch join Работник.Выплаты" вернет 1 * 10 * 5 * 120 = 6000 записей. Запрос-то будет в итоге 1, но, в данном случае, может лучше были бы 3 запроса.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37637680
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Junior Java DeveloperИзвиняюсь, если я не ясно сформулировал вопрос. Вопрос был такой относительно вложенных сущностей. есть 2 стратегии: Lazy и не-Lazy. Как быть, когда в программе требуется оба подхода? То, что если отказаться от Lazy все будет работать без ошибок, я прекрасно понимаю.
для начала, отвечать на посты. когда тебе пишут. Плюс чернил своих не жалеть.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37637745
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
igorolvСледует иметь в виду, что fetch join в hql транслируется в left join в sql. Поэтому если использовать fetch join для загрузки нескольких ассоциаций к одному объекту сразу - можно получить выборку декартового произведения нескольких таблиц.

Например, предположим есть объект "Работник" с detail-ами "Отпуска", "Параметры расчета зарплаты", "Выплаты". Пусть у 1 работника есть 10 отпусков, 5 параметров расчета и 120 выплат. Тогда запрос "select * from Работник fetch join Работник.Отпуска fetch join Работник.Параметры fetch join Работник.Выплаты" вернет 1 * 10 * 5 * 120 = 6000 записей. Запрос-то будет в итоге 1, но, в данном случае, может лучше были бы 3 запроса.
Я прошу прощения, но приведенный вами пример это абсолютная бессмыслица. Такое невозможно сделать одним запросом ни в HQL, ни в SQL. И самое главное - ни один человек, который хоть немного соображает в реляционной алгебре, не будет такого делать.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37637747
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Junior Java DeveloperИзвиняюсь, если я не ясно сформулировал вопрос. Вопрос был такой относительно вложенных сущностей. есть 2 стратегии: Lazy и не-Lazy. Как быть, когда в программе требуется оба подхода? То, что если отказаться от Lazy все будет работать без ошибок, я прекрасно понимаю.Да сказано же уже - ставите по умолчанию Lazy, когда надо не-Lazy, обращаетесь к помощи FETCH JOIN через HQL или критерии.
...
Рейтинг: 0 / 0
Hibernate. N+1. Best practice
    #37637771
igorolv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svenomigorolvСледует иметь в виду, что fetch join в hql транслируется в left join в sql. Поэтому если использовать fetch join для загрузки нескольких ассоциаций к одному объекту сразу - можно получить выборку декартового произведения нескольких таблиц.

Например, предположим есть объект "Работник" с detail-ами "Отпуска", "Параметры расчета зарплаты", "Выплаты". Пусть у 1 работника есть 10 отпусков, 5 параметров расчета и 120 выплат. Тогда запрос "select * from Работник fetch join Работник.Отпуска fetch join Работник.Параметры fetch join Работник.Выплаты" вернет 1 * 10 * 5 * 120 = 6000 записей. Запрос-то будет в итоге 1, но, в данном случае, может лучше были бы 3 запроса.
Я прошу прощения, но приведенный вами пример это абсолютная бессмыслица. Такое невозможно сделать одним запросом ни в HQL, ни в SQL. И самое главное - ни один человек, который хоть немного соображает в реляционной алгебре, не будет такого делать.

Да, в приведенном псевдокоде HQL перепутал местами fetch и join - было поздно. Но сделать-то такое в HQL вполне можно:
"from Sale sale where sale.date > :startDate left join fetch sale.product" ( http://www.javalobby.org/articles/hibernate-query-101/ ).
Этот HQL запрос действительно транслируется в sql-запрос с left join.
А если загружать таким запросом не одну подчиненную коллекцию, а несколько - то количество строк будет равно количеству произведений строк в коллекциях
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate. N+1. Best practice
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]