Поставь аттрибут fetch="select" или вообще убери его (это дефолтное поведеие хибернейта) и скажи результат. Из доки Хибернейта:
fetch (optional — defaults to select): Chooses between outer-join
fetching or sequential select fetching.
Добрый день!
Имеется следующая структура данных:
1. Базовая таблица (содержит Unique ids)
2. Таблица, содержит подмножество unique ids из таблицы 1
3. На уровне java code: базовый класс и наследник
То мне возвращается в листе столько одинаковых объектов, сколько содержится для ID_COLUMN в таблице mapping_table.
Т.е. если таблица mapping_table содержит 2 строки:
1 — 123
1 — 1234
То у меня будет 2 одинаковых объекта child.class в листе. Если 3, то 3.
Спасибо за ответ, похоже проблема в другом, SQL выполняется правильно, но у меня стоит условие (для поддержки постраничного отображения),
что на страницу грузится не больше 20 записей. Такое ощущение, что Hibernate получает 20 SQL строк, делает из них 19 объектов, смотрит, что одного не хватает и копирует объект который "скушал" строки.
Что-то интересное Вы описываете. На мой взгляд дело не в постраничном отображении. Хотя думаю меня поправят если что.
Судя по Вашему ответу, Вы смотрели логи Hibernate и видели формируемый SQL? Можете его выложить?
Здравствуйте, Denis_Orlov, Вы писали:
PAS>>А по теме: https://forum.hibernate.org/viewtopic.php?t=941669,
D_O>Спасибо за ответ, похоже проблема в другом, SQL выполняется правильно, но у меня стоит условие (для поддержки постраничного отображения), D_O>что на страницу грузится не больше 20 записей. Такое ощущение, что Hibernate получает 20 SQL строк, делает из них 19 объектов, смотрит, что одного не хватает и копирует объект который "скушал" строки.
D_O>Есть ли вероятность такого со стороны hibernate?
Здравствуйте, PAS_Tor, Вы писали:
PAS>Что-то интересное Вы описываете. На мой взгляд дело не в постраничном отображении. Хотя думаю меня поправят если что. PAS>Судя по Вашему ответу, Вы смотрели логи Hibernate и видели формируемый SQL? Можете его выложить?
Похоже SQL не понадобится, вот кусок из hibernate tutorial (здесь):
3.3. Removing duplicate objects
The following HQL can be used to retrieve books and their associated chapters where at least one of
the chapter titles includes the word “Hibernate”. The result contains pairs of a book and a chapter.
from Book book join book.chapters chapter
where chapter.title like '%Hibernate%'
For the implicit version of the above query, only the book objects will be included. But to our
surprise the book objects are duplicated. The time of duplication is equal to how many chapters
have “Hibernate” like title.
from Book book
where book.chapters.title like '%Hibernate%'
According to the explanation given by Hibernate, it is a normal behavior since Hibernate always
returns a list of the same size as the underlying JDBC ResultSet. We can use a LinkedHashSet to
filter the duplicate objects while keeping the order of original list.
Query query = session.createQuery(
"from Book book where book.chapters.title like '%Hibernate%'");
List books = query.list();
Set uniqueBooks = new LinkedHashSet(books);
Вообще, думаю, что проблему можно решить с помощью setFetchSize, но ещё не пробовал.
Здравствуйте, Denis_Orlov, Вы писали:
D_O>Query query = session.createQuery( D_O>"from Book book where book.chapters.title like '%Hibernate%'"); D_O>List books = query.list(); D_O>Set uniqueBooks = new LinkedHashSet(books); D_O>[/code]
Это просто праздник какой-то. Вычитать и инстанциировать 3-4 сотни объектов, чтобы потом из них сделать одну через Set?
Китайцы знакомые так же пишут — выбирают все объекты из таблицы, а затем в цикле отбрасывают не нужные.
Здравствуйте, Blazkowicz, Вы писали:
B>Это просто праздник какой-то. Вычитать и инстанциировать 3-4 сотни объектов, чтобы потом из них сделать одну через Set? B>Китайцы знакомые так же пишут — выбирают все объекты из таблицы, а затем в цикле отбрасывают не нужные.
Согласен, вопрос в другом, есть ли решение помимо этого?
D_O>То мне возвращается в листе столько одинаковых объектов, сколько содержится для ID_COLUMN в таблице mapping_table. D_O>Т.е. если таблица mapping_table содержит 2 строки: D_O>1 — 123 D_O>1 — 1234 D_O>То у меня будет 2 одинаковых объекта child.class в листе. Если 3, то 3.
Странные вещи вы рассказываете. Т.е. если из маппинга убрать set, где упоминается mapping_table, то будет работать нормально???
У меня нет ресурсов для проверки прямо сейчас, но возможно проблема здесь, Вам не кажеться?
outer-join="true"
Приведите всё-таки SQL.
Здравствуйте, Denis_Orlov, Вы писали:
D_O>Здравствуйте, Blazkowicz, Вы писали:
B>>Странные вещи вы рассказываете. Т.е. если из маппинга убрать set, где упоминается mapping_table, то будет работать нормально??? D_O>Именно так.
Здравствуйте, Denis_Orlov, Вы писали:
D_O>Здравствуйте, Blazkowicz, Вы писали:
B>>Странные вещи вы рассказываете. Т.е. если из маппинга убрать set, где упоминается mapping_table, то будет работать нормально???
Давайте рассуждать. Происходит следующая картина.
Существует 2 таблицы:
1. Основная
2. Mapping
Связываются они через hibernate mapping как set outer-join="true" — т.е. в нативном SQL left join.
Я в коде для поддержания paging по средством базы через hibernate ставлю:
Что в нативном SQL (Oracle) выглядит как (rownum < pagesize).
Соответственно у нас вынимается pagesize строк.
Но, тут срабатывает left join который для одного unique ID может вернуть не одну строку а столько, сколько в таблице Mapping для этого id есть записей.
Что получаем в конце.
Или hibernate вернёт количество объектов < pagesize, что плохо, или он чтобы количество объектов было равно ожидаемому размножит объект, который
пришлось клеить.
Вот примерное видение ситуации с моей стороны.
Есть идеи?
Здравствуйте, OAR, Вы писали:
OAR>Здравствуйте, Denis_Orlov, Вы писали:
OAR>Поставь аттрибут fetch="select" или вообще убери его (это дефолтное поведеие хибернейта) и скажи результат. Из доки Хибернейта: OAR>fetch (optional — defaults to select): Chooses between outer-join OAR>fetching or sequential select fetching.
Большое спасибо, помогло.
Изменил на fetch="subselect", при такой конфигурации получается более оптимальный SQL, чем при fetch="select".
Здравствуйте, Denis_Orlov, Вы писали:
D_O>Большое спасибо, помогло. D_O>Изменил на fetch="subselect", при такой конфигурации получается более оптимальный SQL, чем при fetch="select".
Смотрите чтобы потом это не вылезло вам в N+1 запрос.
Здравствуйте, Denis_Orlov, Вы писали:
D_O>Здравствуйте, Blazkowicz, Вы писали:
B>>Это просто праздник какой-то. Вычитать и инстанциировать 3-4 сотни объектов, чтобы потом из них сделать одну через Set? B>>Китайцы знакомые так же пишут — выбирают все объекты из таблицы, а затем в цикле отбрасывают не нужные.
D_O>Согласен, вопрос в другом, есть ли решение помимо этого?