powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Простейший SQL запрос Hibernate
37 сообщений из 37, показаны все 2 страниц
Простейший SQL запрос Hibernate
    #37755815
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хочу получить записи в количестве 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
Простейший SQL запрос Hibernate
    #37755840
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для limit нужно использовать setFirst() setMax(), дословно синтаксис не помню - поищите методы
а для ограничения дубликатов - есть то ли баг то ли фича хибернейта, я в другой ветке обсуждал, возможно надо переписать запрос через hql. Но сначала попробуйте методы вначалае и отпишитесь.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755848
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник, это если запрос через HQL писать, то там да, через set*() задается. Но мне интересно именно через Criteria.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755853
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник, я что-то в обертке Spring hibernateTemplate такого вообще не нахожу, я про setMax/First.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755857
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник, и у меян в базе нет дубликатов)

id | visible | name
1 true Дима1
2 true Дима2
3 true Дима3
4 true Дима4
5 true Дима5
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755871
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Простейший SQL запрос Hibernate
    #37755872
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
у тебя join на images, при связи 1:N или N:M limit X,Y начинает играть совсем другими красками.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755880
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpasha, я догадывался об этом) но все таки как сделать чтобы это просто работало) ведь запрос то простейший, почему возникают такие сложности? ) Толи я дурак, то ли хибернате мудрит на пустом месте)
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755884
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdm,

пейджинг перестает работать при eager fetch. Попробуй FetchMode.SELECT.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755890
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vas0, получается классика с LazyInitializationException )
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755906
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Заметил такую особенность, что запрос перестает правильно работать при addOrder(Order.desc("id").
Т.е. если убрать эту запись выборка правильная) Но мне нужно именно desc.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755917
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Простейший SQL запрос Hibernate
    #37755948
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал вот так, вроде работает. Хотя печально все это)

Код: 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
Простейший SQL запрос Hibernate
    #37755953
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdmchpasha, я догадывался об этом) но все таки как сделать чтобы это просто работало) ведь запрос то простейший, почему возникают такие сложности? ) Толи я дурак, то ли хибернате мудрит на пустом месте)

setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755958
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, не сработало, пробывал) и new org.hibernate.transform.DistinctRootEntityResultTransformer() и тоже)
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755967
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Простейший SQL запрос Hibernate
    #37755972
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, сейчас попробую) Я ошибся, CriteriaSpecification.DISTINCT_ROOT_ENTITY не пробовал )
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755973
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

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

И он не будет работать ни в Criteria API ни в HQL, так что твой код, по моему, работает неправильно.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37755984
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vas0Работает distinct, но не setMaxResults(), setFirstResult(). Из-за того что в запросе есть fetch join получаем декартого произведение и пейджинг перестает правильно работать.
А... А почему HQL тогда заработал вдруг?
Тогда через подзапрос можно сделать:
http://floledermann.blogspot.com/2007/10/solving-hibernate-criterias-distinct.html
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756000
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Простейший SQL запрос Hibernate
    #37756002
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, не работает( пробовал и hibernate session и hibernateTemplate. Я думаю дело в том, что в вашем примере нет Order и setMaxResult/setFirstResult. Так что увы, но у меня ничего кроме голого HQL не работает правильно.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756013
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Простейший SQL запрос Hibernate
    #37756022
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, Ваш вариант "почти" работает) У некоторых обьектов event список image правильный, а у одного (последнего) состоит только из одного объекта Image вместо 8)
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756026
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делайте через подзапрос. Внутрений запрос с порядком и пэйджингом только по главной энтити. А внешний запрос с джоином.
Подзапросы на Criteria API через DetachedCriteria делаются.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756044
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
при HQL запросе(который как я писал выше работает правильно), hibernate выдает следующее:

Hibernate: select event*...., images*..., from event left outer join image on event.id=images.parent_id where event.event_visible=1 order by event.id desc

Как я понял Limit'а тут нет, т.е. он что все записи считывает? )
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756076
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, мне кажется тогда уж проще вот так. Не прав?

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
 List<Event> execute = (List<Event>) hibernateTemplate.execute(new HibernateCallback() {

            @Override
            public List<Event> doInHibernate(Session session) {

               
                 List<Event> result = null;
                
                Criteria criteria = session.createCriteria(Event.class);                
                criteria.addOrder(Order.desc("id")).setFirstResult(0).setMaxResults(3);
                
                
                
                result = criteria.list();

                for (Event event : result) {
                    hibernateTemplate.initialize(event.images);                                       
                }


                return result;

            }
        });
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756113
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdmBlazkowicz, мне кажется тогда уж проще вот так. Не прав?
Это N+1 запросов на каждую страницу.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756157
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, я не совсем понял как сделать
авторДелайте через подзапрос. Внутрений запрос с порядком и пэйджингом только по главной энтити. А внешний запрос с джоином. Подзапросы на Criteria API через DetachedCriteria делаются.

Не могли бы вы привести пример.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756164
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdmНе могли бы вы привести пример.
Уже:
http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=934603&msg=12424031
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756174
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczДелайте через подзапрос. Внутрений запрос с порядком и пэйджингом только по главной энтити. А внешний запрос с джоином.
Подзапросы на Criteria API через DetachedCriteria делаются.
Я смотрел) Видимо не увидел среди английских фраз то что вы имели ввиду.
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756188
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пойду разберусь)
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756272
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczrdmНе могли бы вы привести пример.
Уже:
http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=934603&msg=12424031
Пока я что-то не очень понял этот пример)
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756393
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, не получилось вообщем, не понял. Возвращается множество, о котором писал vas0.
Но) Пока писал это сообщение нашел вот такое решение:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
      
List<Event> execute = (List<Event>) hibernateTemplate.execute(new HibernateCallback() {

            @Override
            public List<Event> doInHibernate(Session session) {


                List<Event> result = null;

                Criteria criteria = session.createCriteria(Event.class);
                criteria.setFirstResult(0).setMaxResults(3);
                criteria.addOrder(Order.desc("id"));
                
                             
                  
                    criteria.setProjection(Projections.distinct(
                            Projections.projectionList().add(Projections.id())));
                    
                  
                    
                    List list = criteria.list();
                   
                    List<Long> idlist = new ArrayList<Long>();

                    for (Iterator iditer = list.iterator(); iditer.hasNext();) {
                        Long record = (Long) iditer.next();
                        idlist.add(record);
                    }

                    //Массив с id'шниками
                    Long[] listLong = idlist.toArray(new Long[0]);

                    List<Event> listResult = null;
                  
                   
                    if (idlist.size() > 0) {
                    Query setParameter = session.createQuery("from Event event inner join fetch event.images where event.visible = true AND event.id IN (:mas)").setParameterList("mas", listLong).setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
                    listResult = setParameter.list();
                    } else {
                        return new ArrayList();
                    }
               
                



                return listResult;



            }
        });



        return execute;




В логе хибернейт пишет 2 запроса:

Код: sql
1.
2.
3.
Hibernate: select distinct this_.id as y0_ from event this_ order by this_.id desc limit ?

Hibernate: select event* , image* from event inner join image on event.id=images.parent_id where event.event_visible=1 and (event.id in (? , ? , ?))



Вроде бы правильно? Я прав?
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756623
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdmВроде бы правильно? Я прав?
Что-то похожее, но, в теории, можно ведь вместо списка и подзапросом сделать

WHERE Event.ID IN (SELECT ID FROM ...)
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756745
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczrdmВроде бы правильно? Я прав?
Что-то похожее, но, в теории, можно ведь вместо списка и подзапросом сделать

WHERE Event.ID IN (SELECT ID FROM ...)
Я такой запрос пробовал на SQL, первый работает, а второй нет.
Пишет "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'"

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SELECT id
     , image.parent_id    
     , image.image_id
FROM
  shootride.event
LEFT JOIN image
ON image.parent_id = event.id
WHERE
  event.id IN (1, 2, 3);


SELECT id
     , image.parent_id    
     , image.image_id
FROM
  shootride.event
LEFT JOIN image
ON image.parent_id = event.id
WHERE
  event.id IN (SELECT event.id from event order by event.id limit 0,3);
...
Рейтинг: 0 / 0
Простейший SQL запрос Hibernate
    #37756763
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdmЯ такой запрос пробовал на SQL, первый работает, а второй нет.
Пишет "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'"

ОК
...
Рейтинг: 0 / 0
37 сообщений из 37, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Простейший SQL запрос Hibernate
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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