Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Hibernate DetachedCriteria - дублируются записи 
:(
    Опции темы
brejnev
Дата 10.1.2008, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 18.9.2005

Репутация: нет
Всего: нет



Разбираюсь с критериями в Hibernate3.

Создаю DetachedCriteria, делаю выборку. В итоге - набор дублирующихся сущностей, причем в БД все записи уникальны. Дублирование идет как-попало и от чего зависит так и не понял. 
В результяте упрощения запроса остался такой код:

Код

DetachedCriteria criteria = DetachedCriteria.forClass(QuestionnairePerson.class,"person");
Collection result = getHibernateTemplate().findByCriteria(criteria);


QuestionnairePerson

Код

@Entity
@Table(name = "questionnaireperson")
})
public class QuestionnairePerson implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "fkey", nullable = false)
    private Integer key;

   public QuestionnairePerson() {
    }

    public QuestionnairePerson(Integer fkey) {
        this.key = fkey;
    }

    @Override
    public int hashCode() {
        return getKey().hashCode();
    }

    @Override
    public boolean equals(Object object) {

        if (!(object instanceof QuestionnairePerson)) {
            return false;
        }

        return this.getKey().equals(object);
    }
...
}


В гугле смотрел, так и не поборол баг.

 Работает все нормально если задать такую штуку
Код

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);


Но мне это не нравится, что-то тут не так.
PM MAIL   Вверх
ibodrov
Дата 10.1.2008, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 20.9.2005

Репутация: нет
Всего: нет



Дело не в DetachedCriteria.

Посмотрите, какой SQL генерит Hibernate ("hibernate.show_sql"), наверняка там будут дублирующиеся записи из-за JOIN'ов.
PM MAIL   Вверх
brejnev
Дата 10.1.2008, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 18.9.2005

Репутация: нет
Всего: нет



Цитата

Дело не в DetachedCriteria.

Посмотрите, какой SQL генерит Hibernate ("hibernate.show_sql"), наверняка там будут дублирующиеся записи из-за JOIN'ов.


Хм, завтра на работу приду, попробую.....

Поведение похоже на join, но откуда ему там взяться? Неужели hibernate присоединяет все связанные таблицы smile 
PM MAIL   Вверх
brejnev
Дата 11.1.2008, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 18.9.2005

Репутация: нет
Всего: нет



Код

select answerfill0_.f_person as f4_4_, answerfill0_.fkey as fkey4_, answerfill0_.fkey as fkey127_3_, answerfill0_.f_answer as f3_127_3_, answerfill0_.f_person as f4_127_3_, answerfill0_.fvalue as fvalue127_3_, answer1_.fkey as fkey125_0_, answer1_.f_nextquestion as f3_125_0_, answer1_.f_question as f4_125_0_, answer1_.ftext as ftext125_0_, question2_.fkey as fkey128_1_, question2_.f_questionnaire as f3_128_1_, question2_.ftext as ftext128_1_, question2_.f_type as f4_128_1_, question3_.fkey as fkey128_2_, question3_.f_questionnaire as f3_128_2_, question3_.ftext as ftext128_2_, question3_.f_type as f4_128_2_ 
from tanswerfilled answerfill0_ left outer join tanswer answer1_ on answerfill0_.f_answer=answer1_.fkey 
left outer join tquestion question2_ on answer1_.f_nextquestion=question2_.fkey 
left outer join tquestion question3_ on answer1_.f_question=question3_.fkey where answerfill0_.f_person=?


Вот такой sql-код генерит хитбернейт-критерий в первом посте. Как ему сказать, чтобы он не соединял join-ом таблицы? Мне всего-лишь надо выбрать сущности из одой таблицы.
PM MAIL   Вверх
iluvatar
Дата 11.1.2008, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 266
Регистрация: 17.9.2007

Репутация: 4
Всего: 4



насколько помню у Criteria нет какого-либо вменяемого решения distinct-проблемы
сам когда-то задавался подобным вопросом. как временный вариант тогда выбрал такой метод:
    сначала выбираем ТОЛЬКО id:
         
Код

                    Criteria crit = session.createCriteria(Class.class)
                            ....
                            .setProjection(Projections.distinct(Projections.projectionList().add(Projections.id()) ))
                            .setFirstResult(startPos).setMaxResults(maxResults)
         
  
    а потом  по списку id получаем те записи какие хотим.

НО! если существует какой-либо order by, то все поля по которым идет сортировка необходимо указать в projectionList():
Код

                    Criteria crit = session.createCriteria(Class.class)
                             ....
                            .setProjection(Projections.distinct(Projections.projectionList()
                                    .add(Projections.id())
                                    .add(Projections.property("field1"))
                                    .add(Projections.property("field2"))))
                            .setFirstResult(startPos).setMaxResults(maxResults)
                            .addOrder(Order.asc("field1"))
                            .addOrder(Order.asc("field2"));

  получаем список полей, вручную получаем список ТОЛЬКО из первых элементов списка (только id), по id получаем список записей.

Есть еще один вариант с ипсользованием Criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY), но этоот способ выполняет distinct ПОСЛЕ выполнения запроса, т.е. средствами не БД, а Hibernate, что не подходит если осуществляется постраничное ранжирование.

Кстати, это была одна из причин перехода на HQL, чего и вамсоветую.

Добавлено через 2 минуты и 31 секунду
Цитата(brejnev @ 11.1.2008,  08:31)
Код

select answerfill0_.f_person as f4_4_, answerfill0_.fkey as fkey4_, answerfill0_.fkey as fkey127_3_, answerfill0_.f_answer as f3_127_3_, answerfill0_.f_person as f4_127_3_, answerfill0_.fvalue as fvalue127_3_, answer1_.fkey as fkey125_0_, answer1_.f_nextquestion as f3_125_0_, answer1_.f_question as f4_125_0_, answer1_.ftext as ftext125_0_, question2_.fkey as fkey128_1_, question2_.f_questionnaire as f3_128_1_, question2_.ftext as ftext128_1_, question2_.f_type as f4_128_1_, question3_.fkey as fkey128_2_, question3_.f_questionnaire as f3_128_2_, question3_.ftext as ftext128_2_, question3_.f_type as f4_128_2_ 
from tanswerfilled answerfill0_ left outer join tanswer answer1_ on answerfill0_.f_answer=answer1_.fkey 
left outer join tquestion question2_ on answer1_.f_nextquestion=question2_.fkey 
left outer join tquestion question3_ on answer1_.f_question=question3_.fkey where answerfill0_.f_person=?


Вот такой sql-код генерит хитбернейт-критерий в первом посте. Как ему сказать, чтобы он не соединял join-ом таблицы? Мне всего-лишь надо выбрать сущности из одой таблицы.

насчет подключения вложенных таблиц отвечают lazy и fetch в мэппинге.
PM MAIL ICQ   Вверх
mariyasmirnova01
Дата 24.9.2015, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 21.8.2015

Репутация: нет
Всего: нет



PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.1315 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.