Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Простейший SQL запрос Hibernate / 25 сообщений из 37, страница 1 из 2
16.04.2012, 16:57:20
    #37755815
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Хочу получить записи в количестве n, начиная с записи m, т.е. что-то типа

select * from testtable where visible = true order by id limit 0,5

Короче говоря, первые пять записей таблицы.


Делаю вот так:
Код: java
1.
2.
3.
4.
findByCriteria = hibernateTemplate.findByCriteria(
                    DetachedCriteria.forClass(Event.class).
                    setFetchMode("images", FetchMode.JOIN).
                    add(Restrictions.eq("visible", true)).addOrder(Order.desc("id")), 0,5);



Получаю список с повторяющимися элементами, причем количество повторений для разных id разное.

Как сделать правильно? )
...
Рейтинг: 0 / 0
16.04.2012, 17:12:39
    #37755840
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
для limit нужно использовать setFirst() setMax(), дословно синтаксис не помню - поищите методы
а для ограничения дубликатов - есть то ли баг то ли фича хибернейта, я в другой ветке обсуждал, возможно надо переписать запрос через hql. Но сначала попробуйте методы вначалае и отпишитесь.
...
Рейтинг: 0 / 0
16.04.2012, 17:15:18
    #37755848
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
забыл ник, это если запрос через HQL писать, то там да, через set*() задается. Но мне интересно именно через Criteria.
...
Рейтинг: 0 / 0
16.04.2012, 17:18:14
    #37755853
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
забыл ник, я что-то в обертке Spring hibernateTemplate такого вообще не нахожу, я про setMax/First.
...
Рейтинг: 0 / 0
16.04.2012, 17:21:12
    #37755857
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
забыл ник, и у меян в базе нет дубликатов)

id | visible | name
1 true Дима1
2 true Дима2
3 true Дима3
4 true Дима4
5 true Дима5
...
Рейтинг: 0 / 0
16.04.2012, 17:25:32
    #37755871
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
rdmзабыл ник, и у меян в базе нет дубликатов)

id | visible | name
1 true Дима1
2 true Дима2
3 true Дима3
4 true Дима4
5 true Дима5

Я не про базу - при определенных условиях, критерия возвращает дубликаты, там довольно долго обьяснять, если будет время напишу подробнее.

Насчет setFirst setMax - не работал через spring template, в обычном хибернейт это делается так

Criteria criteria = session.createCriteria(Student.class);
criteria.setFirstResult(1);

Если таких методовдействительно нет - то имхо чет они замутили, надо гуглить
...
Рейтинг: 0 / 0
16.04.2012, 17:25:48
    #37755872
chpasha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
у тебя join на images, при связи 1:N или N:M limit X,Y начинает играть совсем другими красками.
...
Рейтинг: 0 / 0
16.04.2012, 17:28:51
    #37755880
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
chpasha, я догадывался об этом) но все таки как сделать чтобы это просто работало) ведь запрос то простейший, почему возникают такие сложности? ) Толи я дурак, то ли хибернате мудрит на пустом месте)
...
Рейтинг: 0 / 0
16.04.2012, 17:29:58
    #37755884
vas0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
rdm,

пейджинг перестает работать при eager fetch. Попробуй FetchMode.SELECT.
...
Рейтинг: 0 / 0
16.04.2012, 17:33:46
    #37755890
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
vas0, получается классика с LazyInitializationException )
...
Рейтинг: 0 / 0
16.04.2012, 17:46:55
    #37755906
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Заметил такую особенность, что запрос перестает правильно работать при addOrder(Order.desc("id").
Т.е. если убрать эту запись выборка правильная) Но мне нужно именно desc.
...
Рейтинг: 0 / 0
16.04.2012, 17:54:48
    #37755917
vas0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
rdmЗаметил такую особенность, что запрос перестает правильно работать при addOrder(Order.desc("id").
Т.е. если убрать эту запись выборка правильная) Но мне нужно именно desc. Скорее всего у тебя при порядке аsc идут коллекции images, в которых не больше одного элемента. А при desc, есть коллекции images с несколькими элементами и получаешь такое декартого произведение:

event1 image1
event1 image2
event1 image3
event2 image1
event3 image1
event4 image1
event5 image1
...
Рейтинг: 0 / 0
16.04.2012, 18:16:48
    #37755948
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Сделал вот так, вроде работает. Хотя печально все это)

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
 
List<Event> execute = (List<Event>) hibernateTemplate.execute(new HibernateCallback() {
            @Override
            public List<Event> doInHibernate(Session session) {
               
                
                List<Event> list = session.createQuery("from Event e left join fetch e.images where e.visible = true order by e.id                desc").setFirstResult(0).setMaxResults(3).list();
                
               
                
                return list;
            }
        });



        return execute;
...
Рейтинг: 0 / 0
16.04.2012, 18:20:32
    #37755953
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
rdmchpasha, я догадывался об этом) но все таки как сделать чтобы это просто работало) ведь запрос то простейший, почему возникают такие сложности? ) Толи я дурак, то ли хибернате мудрит на пустом месте)

setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
...
Рейтинг: 0 / 0
16.04.2012, 18:23:18
    #37755958
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Blazkowicz, не сработало, пробывал) и new org.hibernate.transform.DistinctRootEntityResultTransformer() и тоже)
...
Рейтинг: 0 / 0
16.04.2012, 18:28:53
    #37755967
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
rdmBlazkowicz, не сработало, пробывал) и new org.hibernate.transform.DistinctRootEntityResultTransformer() и тоже)
У нас вот так работает без проблем:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
        
return getHibernateTemplate().execute(new HibernateCallback<List<Entity>>() {
            @Override
            public List<Entity> doInHibernate(Session session) throws HibernateException, SQLException {
                Criteria sc = session.createCriteria(Entity.class);
                sc.setFetchMode("association1", FetchMode.JOIN);
                sc.setFetchMode("association2", FetchMode.JOIN);
                sc.add(Restrictions.eq("association1", associated));
                sc.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
                @SuppressWarnings("unchecked")
                List<Entity> list = sc.list();
                return list;
            }
        });
...
Рейтинг: 0 / 0
16.04.2012, 18:33:10
    #37755972
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Blazkowicz, сейчас попробую) Я ошибся, CriteriaSpecification.DISTINCT_ROOT_ENTITY не пробовал )
...
Рейтинг: 0 / 0
16.04.2012, 18:33:26
    #37755973
vas0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Blazkowicz,

Работает distinct, но не setMaxResults(), setFirstResult(). Из-за того что в запросе есть fetch join получаем декартого произведение и пейджинг перестает правильно работать.
...
Рейтинг: 0 / 0
16.04.2012, 18:36:03
    #37755977
vas0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
rdm,

И он не будет работать ни в Criteria API ни в HQL, так что твой код, по моему, работает неправильно.
...
Рейтинг: 0 / 0
16.04.2012, 18:39:11
    #37755984
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
vas0Работает distinct, но не setMaxResults(), setFirstResult(). Из-за того что в запросе есть fetch join получаем декартого произведение и пейджинг перестает правильно работать.
А... А почему HQL тогда заработал вдруг?
Тогда через подзапрос можно сделать:
http://floledermann.blogspot.com/2007/10/solving-hibernate-criterias-distinct.html
...
Рейтинг: 0 / 0
16.04.2012, 18:49:36
    #37756000
vas0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Blazkowicz,

Все зависит от данных. На некоторых может показаться что все работает правильно. Допустим отношение event/image, если у каждого event в коллекции будет по одному image. При fetch join можем получить такое декартово произведение:
event1 image1
event2 image2
event3 image3

Если же попадутся коллекции с более чем одним image, то можем получить:
event1 image1
event1 image2
event1 image3
Persistence with HibernateQuery execution options that are based on the SQL result rows, such as pagination
with setMaxResults()/setFirstResult(), are semantically incorrect
if a collection is eagerly fetched. If you have an eager fetched collection
in your query, at the time of writing, Hibernate falls back to limiting the
result in-memory, instead of using SQL. This may be less efficient, so we
don’t recommend the use of JOIN FETCH with setMaxResults()/set-
FirstResult(). Future versions of Hibernate may fall back to a different
SQL query strategy (such as two queries and subselect fetching) if setMaxResults()/
setFirstResult() is used in combination with a JOIN FETCH.
...
Рейтинг: 0 / 0
16.04.2012, 18:52:01
    #37756002
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Blazkowicz, не работает( пробовал и hibernate session и hibernateTemplate. Я думаю дело в том, что в вашем примере нет Order и setMaxResult/setFirstResult. Так что увы, но у меня ничего кроме голого HQL не работает правильно.
...
Рейтинг: 0 / 0
16.04.2012, 18:56:28
    #37756013
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
vas0rdm,

И он не будет работать ни в Criteria API ни в HQL, так что твой код, по моему, работает неправильно.

у меня в таблице 4 записи event (id = 1,2,3,4)

1 event -> 6 записей в таблице image
2 event -> 3 записи image
3 event -> 8 записей image
4 event -> 4 записи image

отношения между Event и Image - OneToMany

На таких данных HQL запрос работает правильно.
...
Рейтинг: 0 / 0
16.04.2012, 19:03:14
    #37756022
rdm
rdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Blazkowicz, Ваш вариант "почти" работает) У некоторых обьектов event список image правильный, а у одного (последнего) состоит только из одного объекта Image вместо 8)
...
Рейтинг: 0 / 0
16.04.2012, 19:06:51
    #37756026
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Простейший SQL запрос Hibernate
Делайте через подзапрос. Внутрений запрос с порядком и пэйджингом только по главной энтити. А внешний запрос с джоином.
Подзапросы на Criteria API через DetachedCriteria делаются.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Простейший SQL запрос Hibernate / 25 сообщений из 37, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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