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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> jpa pagination медленно работает 
V
    Опции темы
dementiev
Дата 16.2.2010, 01:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



делаю пагинацию, включён кэш 2го уровня. Через хибер работает нормально, через jpa же работает в пару раз медленнее. 
Код

       final String hql = "from Employee e "
               + "left join fetch e.positionedEmployees as p "
               + "left join fetch p.address as a "
               + "left join fetch p.company as c "
               + "left join fetch a.city as city "
               + "left join fetch city.country as country "
               + "order by e.id";

return (List<Employee>) getJpaTemplate().execute(new JpaCallback() {

           public Object doInJpa(EntityManager em) throws PersistenceException {
               Query query = em.createQuery(hql);
               query.setFlushMode(FlushModeType.COMMIT); //synchronize with db
               query.setHint("org.hibernate.cacheable", true);//2nd level cache
               query.setFirstResult(startNumber);
               query.setMaxResults( numberToRetrieve);
               List result = query.getResultList();
               return result;
           }
       });



Проблемы:
1) работает гораздо медленнее, чем через хибер+критерию
2) запрос кэшируется, т.е. новые запросы берутся из кэша.
В хибере тоже стоит кэш, но там он срабатывает, если я беру ту страницу, которую уже брал.
В jpa же он всегда срабатывает(не пойму откуда у него уже есть запрос с такими параметрами!)
буду рад ответам). Под параметрами я подразумеваю startNumber и numberToRetrieve.
Отключил эту строку: 
Код

query.setHint("org.hibernate.cacheable", true);//2nd level cache


теперь запросы не кэшируются, но работает гораздо медленнее, чем через хибер + критерию.
PM MAIL   Вверх
dementiev
Дата 17.2.2010, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



суть ошибки кратко: 
jpa тянет сразу все данные, несмотря на 

Код

query.setFirstResult(startNumber);
query.setMaxResults( numberToRetrieve);


Поменял left join на inner join - стало работать быстрее, т.к. берётся меньше объектов. 
Но, почему в хибере ограничения для пагинации срабатывают, а в jpa нет?
PM MAIL   Вверх
dementiev
Дата 18.2.2010, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



переделал через jpa+criteria - стало работать быстрее, чем через hibernate+criteria. Единственный минус - 100ая страница(на каждой по 100 записей) берётся около 2х секунд, первые 10 страниц - около 0 секунд.
Код

        return (List<MyObject>) getJpaTemplate().execute(new JpaCallback() {

            public Object doInJpa(EntityManager em) throws PersistenceException {
                Criteria criteria = ((Session) em.getDelegate()).createCriteria(MyObject.class);
                criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
                //int pageNumber = 20;
                criteria.setCacheable(true);
                criteria.setFirstResult(startNumber);
                criteria.setMaxResults(numberToRetrieve);
                List<MyObject> result = criteria.list();              
                return result;
            }
        });


Облазил весь гугль, так и не понял, почему jpa+hql сразу брало все записи в память, несмотря на 
Код

               query.setFirstResult(startNumber);
               query.setMaxResults( numberToRetrieve);

 
PM MAIL   Вверх
Restavrator
Дата 19.2.2010, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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




Для точного ответа надо смотреть конкретную реализацию, но думаю дело в следующем (по крайне мере для 1 примера):

Запрос использует join для "подтягивания" данных по схеме one-to-many

Т.к. пагинация делается для корневого класа, то  в этом случае простого ограничения на выбор строк в запросе недостаточно.
Поэтому JPA делает пагинацию в памяти.
А хибернейт делает ограничение по выбираемым строкам, но количество корневых объектов не всегда будет равно размеру страницы.

Хибернейт в более старой версии тоже использовал в таком случае пагинацию в памяти, но потом поменял подход.

PM MAIL   Вверх
dementiev
Дата 20.2.2010, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



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

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

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


 




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


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

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