переход на спящий режим приводит к вызовам выбора и обновления - PullRequest
1 голос
/ 16 августа 2011

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

List<SomeData> dataList = (List<SomeData>) session.getCurrentSession()
    .createQuery("from SomeData ad where ad.bar = :bar order    by ad.id.name")
    .setString("bar", foo)
    .setFirstResult(i*PAGE_SIZE)
    .setMaxResults(PAGE_SIZE)
    .setFetchSize(PAGE_SIZE) // page_size is 1000 in my case
    .list();

и

List<SomeData> datalist= (List<SomeData>) session.getCurrentSession()
    .createCriteria(SomeData.class)
    .addOrder(Order.asc("id.name"))
    .add(Expression.eq("bar", foo))
    .setFirstResult(i*PAGE_SIZE)
    .setMaxResults(PAGE_SIZE)
    .list();

У меня это в цикле for, и каждый раз, когда запускается этот запрос, время выполнения увеличивается. Первый вызов возвращается через 100 мс, второй через 150, а 5-й вызов занимает 2 секунды и т. Д.

Просматривая журналы сервера (MySql 5.1.36), я вижу, что запрос select действительно генерируется с помощью предложения LIMIT, но для каждой возвращаемой записи hibernate по какой-то причине также генерирует запрос на обновление. после первого результата он обновляет 1000 записей, после второго результата он обновляет 2000 записей и так далее. Таким образом, для страницы размером 1000 и 5 итераций цикла база данных получает 15 000 запросов (5K + 4K + 3K + 2K + 1K). Почему это происходит?

Я попытался сделать собственный запрос SQL, и он работал как положено. Запрос

List asins = (List) session.getCurrentSession()
    .createSQLQuery("SELECT * FROM some_data where foo = :foo order by bar
           LIMIT :from , :page")
    .addScalar(..)
    .setInteger("page", PAGE_SIZE)
    .setInteger("from", (i*PAGE_SIZE))
    ... // set other params 
    .list();

Мой класс отображения имеет сеттеры / геттеры для объекта blob как

void setSomeBlob(Blob blob){
    this.someByteArray = this.toByteArray(blob)
}

void Blob getSomeBlob(){
    return Hibernate.createBlob(someByteArray)
}

1 Ответ

1 голос
/ 16 августа 2011

Включите ведение журнала связанных параметров (вы можете сделать это, установив уровень журнала «org.hibernate.type» в «TRACE»), чтобы увидеть, что конкретно обновляется.

Скорее всего, вы изменяете сущности после того, как они были загружены - явно или неявно (например, возвращая другое значение из метода получения или используя где-то значение по умолчанию).

Другая возможность состоит в том, что вы недавно изменили (одну из) таблицы, из которых выбираете, и столбец по умолчанию в таблице не соответствует значению по умолчанию в объекте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...