|
|
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Помогите разобраться. Разбираюсь с Hibernate, стало интересно вот что. Прочитал тут про проблему n+1. Что если у нас есть вложенная сущность, то происходит минимум 2 запроса к БД, вместо одного. Прочитал также про пути решения: 1. @Fetch 2. FetchMode.EAGER 3. @Batch Но что делать, если в одном участке программы мне нужна Lazy загрузка объекта, а в другом полная? Какие есть пути решения? Может быть есть какой-то специальный паттерн проектирования для этого? Как это реализовать? Буду благодарен за простой пример или ссылку на него. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2012, 12:52:30 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Junior Java Developer , Если нужна Lazy - делаете Lazy. Если нужна полная - делаете HQL запрос с FETCH JOIN. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2012, 12:58:29 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Junior Java Developer, нечётко сформулировал проблему. - какая разница сколько запросов? Имеет значение только при оптимизации. - есть проблема с Lazy. Но, сабж про исключения на отложенной загрузке , продиктован только 1) внимательностью при программировании и 2) отсутствием механизмов автоматизации ТОЛЬКО этого вопроса. 1 - это, никакая IDE не поймёт сама, какие поля надо метить как LAZY 2 - это, каждый "догружает" объекты в ГУИ сам своим способом. Бери себе самый простой - ГРУЗИ ВСЁ СРАЗУ, если обратного не требует ТЗ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2012, 13:03:48 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
мммм. Даже не в этом проблема :) Хибер аккуратно и умно всё делает с LAZY. При первом обращении к полю - он догружает объекты. Проблема в том, что он закрывает соединение с БД слишком быстро. А потом ничего не помнит - память короткая :) Поэтому, если надо не загруженный объект, а соединение с БД закрыто - будет исключение. Парадокс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2012, 13:08:55 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Petro123- какая разница сколько запросов? Имеет значение только при оптимизации. Это не оптимизация. Это просто здравый смысл. Petro123- есть проблема с Lazy. Проблема с lazy заканчивается ровно тогда, когда разбираешься с ленивой загрузкой. Petro123Бери себе самый простой - ГРУЗИ ВСЁ СРАЗУ, если обратного не требует ТЗ. Да-да, а потом говорят, что hibernate - тормозящая гадость. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2012, 13:10:09 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Petro123Junior Java Developer, нечётко сформулировал проблему. - какая разница сколько запросов? Имеет значение только при оптимизации. - есть проблема с Lazy. Но, сабж про исключения на отложенной загрузке , продиктован только 1) внимательностью при программировании и 2) отсутствием механизмов автоматизации ТОЛЬКО этого вопроса. 1 - это, никакая IDE не поймёт сама, какие поля надо метить как LAZY 2 - это, каждый "догружает" объекты в ГУИ сам своим способом. Бери себе самый простой - ГРУЗИ ВСЁ СРАЗУ, если обратного не требует ТЗ. Petro123мммм. Даже не в этом проблема :) Хибер аккуратно и умно всё делает с LAZY. При первом обращении к полю - он догружает объекты. Проблема в том, что он закрывает соединение с БД слишком быстро. А потом ничего не помнит - память короткая :) Поэтому, если надо не загруженный объект, а соединение с БД закрыто - будет исключение. Парадокс.Вынужден констатировать, что вы абсолютно не поняли вопроса автора. Речь идет про N+1 проблему и про то, как эффективно реализовывать разные стратегии загрузки графов объектов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2012, 13:26:33 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
svenom, дык я и сказал, что не понял проблему. :) Вынужден констатировать, что много букффф вместо проблемы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2012, 13:32:26 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Извиняюсь, если я не ясно сформулировал вопрос. Вопрос был такой относительно вложенных сущностей. есть 2 стратегии: Lazy и не-Lazy. Как быть, когда в программе требуется оба подхода? То, что если отказаться от Lazy все будет работать без ошибок, я прекрасно понимаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2012, 22:51:30 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Junior Java Developer, Я когда делал небольшой проект на hibernate, почти все ассоациации пометил как lazy и при необходимости просто писал нужный мне HQL. В результате вместо страшного количества запросов (на используемых данных вроде 20 было, а то и тридцать) получил 1 запрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2012, 23:02:16 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Следует иметь в виду, что 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 запроса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2012, 02:01:39 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Junior Java DeveloperИзвиняюсь, если я не ясно сформулировал вопрос. Вопрос был такой относительно вложенных сущностей. есть 2 стратегии: Lazy и не-Lazy. Как быть, когда в программе требуется оба подхода? То, что если отказаться от Lazy все будет работать без ошибок, я прекрасно понимаю. для начала, отвечать на посты. когда тебе пишут. Плюс чернил своих не жалеть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2012, 09:20:58 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
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. И самое главное - ни один человек, который хоть немного соображает в реляционной алгебре, не будет такого делать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2012, 10:15:38 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
Junior Java DeveloperИзвиняюсь, если я не ясно сформулировал вопрос. Вопрос был такой относительно вложенных сущностей. есть 2 стратегии: Lazy и не-Lazy. Как быть, когда в программе требуется оба подхода? То, что если отказаться от Lazy все будет работать без ошибок, я прекрасно понимаю.Да сказано же уже - ставите по умолчанию Lazy, когда надо не-Lazy, обращаетесь к помощи FETCH JOIN через HQL или критерии. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2012, 10:16:26 |
|
||
|
Hibernate. N+1. Best practice
|
|||
|---|---|---|---|
|
#18+
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. А если загружать таким запросом не одну подчиненную коллекцию, а несколько - то количество строк будет равно количеству произведений строк в коллекциях ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2012, 10:30:42 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=37637468&tid=2132707]: |
0ms |
get settings: |
9ms |
get forum list: |
25ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
52ms |
get topic data: |
16ms |
get forum data: |
4ms |
get page messages: |
84ms |
get tp. blocked users: |
2ms |
| others: | 335ms |
| total: | 537ms |

| 0 / 0 |
