Hibernate mapping problems
От: Denis_Orlov  
Дата: 07.10.09 07:49
Оценка:
Добрый день!
Имеется следующая структура данных:
1. Базовая таблица (содержит Unique ids)
2. Таблица, содержит подмножество unique ids из таблицы 1
3. На уровне java code: базовый класс и наследник

Имеется вот такой вот hibernate mapping:
<class name="base.class" table="base_table">
    <id name="id" type="java.lang.Long" unsaved-value="null" column="ID_COLUMN">
      <generator class="assigned" />
    </id>
    
    <property ...
                       
    </joined-subclass>    
    
       <joined-subclass name="child.class" table="child_table">
        <key column="ID_COLUMN"/>
        
        <property ....

    <set 
       name="spotIds"
       lazy="false"
           fetch="join"
           outer-join="true"
       table="mapping_table">
       <key column="ID_COLUMN"></key>
       <element type="java.lang.Long" column="MAPPING_ID" not-null="true"/> 
    </set>    
    </joined-subclass>
    
  </class>
</hibernate-mapping>


Проблема с в том, что когда я выполняю код типа:
Criteria criteria = session.createCriteria(child.class);
criteria.list();

То мне возвращается в листе столько одинаковых объектов, сколько содержится для ID_COLUMN в таблице mapping_table.
Т.е. если таблица mapping_table содержит 2 строки:
1 — 123
1 — 1234
То у меня будет 2 одинаковых объекта child.class в листе. Если 3, то 3.

В чём может быть проблема?
Re: Hibernate mapping problems
От: PAS_Tor Германия http://passtor.blogspot.com/
Дата: 07.10.09 07:58
Оценка:
В критерионах. Используйте HQL.

А по теме: https://forum.hibernate.org/viewtopic.php?t=941669,

Здравствуйте, Denis_Orlov, Вы писали:

D_O>В чём может быть проблема?
Follow my blog @ http://passtor.blogspot.com/
Re[2]: Hibernate mapping problems
От: Denis_Orlov  
Дата: 07.10.09 08:23
Оценка:
PAS>А по теме: https://forum.hibernate.org/viewtopic.php?t=941669,

Спасибо за ответ, похоже проблема в другом, SQL выполняется правильно, но у меня стоит условие (для поддержки постраничного отображения),
что на страницу грузится не больше 20 записей. Такое ощущение, что Hibernate получает 20 SQL строк, делает из них 19 объектов, смотрит, что одного не хватает и копирует объект который "скушал" строки.

Есть ли вероятность такого со стороны hibernate?
Re[3]: Hibernate mapping problems
От: PAS_Tor Германия http://passtor.blogspot.com/
Дата: 07.10.09 08:32
Оценка:
Что-то интересное Вы описываете. На мой взгляд дело не в постраничном отображении. Хотя думаю меня поправят если что.
Судя по Вашему ответу, Вы смотрели логи 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?
Follow my blog @ http://passtor.blogspot.com/
Re[4]: Hibernate mapping problems
От: Denis_Orlov  
Дата: 07.10.09 08:50
Оценка:
Здравствуйте, 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, но ещё не пробовал.
Re[5]: Hibernate mapping problems
От: Blazkowicz Россия  
Дата: 07.10.09 09:54
Оценка:
Здравствуйте, 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?
Китайцы знакомые так же пишут — выбирают все объекты из таблицы, а затем в цикле отбрасывают не нужные.
Re[6]: Hibernate mapping problems
От: Denis_Orlov  
Дата: 07.10.09 10:17
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Это просто праздник какой-то. Вычитать и инстанциировать 3-4 сотни объектов, чтобы потом из них сделать одну через Set?

B>Китайцы знакомые так же пишут — выбирают все объекты из таблицы, а затем в цикле отбрасывают не нужные.

Согласен, вопрос в другом, есть ли решение помимо этого?
Re: Hibernate mapping problems
От: Blazkowicz Россия  
Дата: 07.10.09 10:26
Оценка:
Здравствуйте, Denis_Orlov, Вы писали:


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, то будет работать нормально???
Re[2]: Hibernate mapping problems
От: Denis_Orlov  
Дата: 07.10.09 10:31
Оценка:
Здравствуйте, Blazkowicz, Вы писали:


B>Странные вещи вы рассказываете. Т.е. если из маппинга убрать set, где упоминается mapping_table, то будет работать нормально???

Именно так.
Re[3]: Hibernate mapping problems
От: PAS_Tor Германия http://passtor.blogspot.com/
Дата: 07.10.09 10:41
Оценка:
У меня нет ресурсов для проверки прямо сейчас, но возможно проблема здесь, Вам не кажеться?
outer-join="true"


Приведите всё-таки SQL.

Здравствуйте, Denis_Orlov, Вы писали:

D_O>Здравствуйте, Blazkowicz, Вы писали:


B>>Странные вещи вы рассказываете. Т.е. если из маппинга убрать set, где упоминается mapping_table, то будет работать нормально???

D_O>Именно так.
Follow my blog @ http://passtor.blogspot.com/
Re[3]: Hibernate mapping problems
От: Denis_Orlov  
Дата: 07.10.09 10:45
Оценка:
Здравствуйте, Denis_Orlov, Вы писали:

D_O>Здравствуйте, Blazkowicz, Вы писали:


B>>Странные вещи вы рассказываете. Т.е. если из маппинга убрать set, где упоминается mapping_table, то будет работать нормально???


Давайте рассуждать. Происходит следующая картина.
Существует 2 таблицы:
1. Основная
2. Mapping

Связываются они через hibernate mapping как set outer-join="true" — т.е. в нативном SQL left join.

Я в коде для поддержания paging по средством базы через hibernate ставлю:
criteria.setMaxResults(pagesize);
criteria.setFirstResult(firstresult);


Что в нативном SQL (Oracle) выглядит как (rownum < pagesize).
Соответственно у нас вынимается pagesize строк.

Но, тут срабатывает left join который для одного unique ID может вернуть не одну строку а столько, сколько в таблице Mapping для этого id есть записей.
Что получаем в конце.

Или hibernate вернёт количество объектов < pagesize, что плохо, или он чтобы количество объектов было равно ожидаемому размножит объект, который
пришлось клеить.

Вот примерное видение ситуации с моей стороны.
Есть идеи?
Re[4]: Hibernate mapping problems
От: Denis_Orlov  
Дата: 07.10.09 11:20
Оценка:
Здравствуйте, PAS_Tor, Вы писали:

PAS>У меня нет ресурсов для проверки прямо сейчас, но возможно проблема здесь, Вам не кажеться?

PAS>
PAS>outer-join="true"
PAS>


Удаление outer-join="true" не помогло.
Re[4]: Hibernate mapping problems
От: OAR  
Дата: 07.10.09 13:00
Оценка: 2 (1)
Здравствуйте, Denis_Orlov, Вы писали:

Поставь аттрибут fetch="select" или вообще убери его (это дефолтное поведеие хибернейта) и скажи результат. Из доки Хибернейта:
fetch (optional — defaults to select): Chooses between outer-join
fetching or sequential select fetching.
Re[5]: Hibernate mapping problems
От: Denis_Orlov  
Дата: 08.10.09 07:32
Оценка:
Здравствуйте, 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".
Re[6]: Hibernate mapping problems
От: Blazkowicz Россия  
Дата: 08.10.09 07:41
Оценка:
Здравствуйте, Denis_Orlov, Вы писали:

D_O>Большое спасибо, помогло.

D_O>Изменил на fetch="subselect", при такой конфигурации получается более оптимальный SQL, чем при fetch="select".

Смотрите чтобы потом это не вылезло вам в N+1 запрос.
Re[7]: Hibernate mapping problems
От: Sergey Astakhov Россия  
Дата: 08.10.09 19:28
Оценка:
Здравствуйте, Denis_Orlov, Вы писали:

D_O>Здравствуйте, Blazkowicz, Вы писали:


B>>Это просто праздник какой-то. Вычитать и инстанциировать 3-4 сотни объектов, чтобы потом из них сделать одну через Set?

B>>Китайцы знакомые так же пишут — выбирают все объекты из таблицы, а затем в цикле отбрасывают не нужные.

D_O>Согласен, вопрос в другом, есть ли решение помимо этого?


Использовать подзапросы в паре с exist/in.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.