2010-11-09 2 views
1

Я использую выборку hibernate для повышения производительности запросов. В моей persistence.xml я добавил следующие настройки:Hibernate: Неожиданный порядок выборки для пакетной выборки

<property name="hibernate.default_batch_fetch_size" value="50"/> 

У меня есть объект A, который имеет 1: N отношение к сущности B. Данные для связи скачиваются лениво. Теперь у меня есть следующая ситуация:.

  • загружаю 10000 объектов типа А из БД
  • Я итерацию над этими объектами и инициализирует ленивое отношение по телефону a.getBs() размер()
  • При этом hibernate не только инициализирует зависимость для текущего объекта, но дополнительно загружает зависимость для 49 дополнительных объектов из списка. Такое поведение ожидается.

Сгенерированный SQL выглядит примерно так:

select 
    b0_.SOMETHING as SOMETHING1_1_, 
    ... 
from 
    XYZ.B b0_ 
where 
    b0_.A_ID in (
     ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ... 
    ) 

Моя реальная проблема заключается в том, что спящий режим не загружается сущностей из списка результатов в ожидаемом порядке. Когда я получаю доступ к первой записи из списка, он не загружает данные для объектов 2-50, но загружает данные из 49 случайных записей из списка. (например, он может инициализировать данные объектов 3, 7, 100, 2001, ...). Такое поведение довольно странно, и мне интересно, как его изменить для загрузки данных в ожидаемом порядке.

Текущие проблемы, связанные с описанным поведением.

  • Использование памяти. В то время как итерация по спящему списку списка инициализирует большое количество данных, что потребуется МНОГО позже. В дополнение к алгоритму сверху я добавил код, который удаляет обработанные записи из списка и вызывает session.evict (entity), чтобы сделать объект подходящим для сбора мусора. Это, конечно, сейчас не работает.
  • Скорость запроса очень медленная в начале итерации, поскольку спящий режим запрашивает db почти для каждого обработанного объекта. Это вызывает проблемы, поскольку я пишу объекты в поток веб-приложения для загрузки во время обработки. В результате скорость загрузки очень медленная в начале и ускоряется, когда больше объектов загружено в память и требуется меньше вызовов db.

Большое спасибо за вашу помощь и наилучшими пожеланиями

Томас

+0

Вы используете списки итераторов()? – KarlP

+0

Я протестировал итератор и новый цикл for (для (A a: resultlist)) – Thomas

ответ

2

Когда вы говорите, что Hibernate не загружается сущностей в ожидаемом порядке, вы сказали ему, что ожидаемый заказ? То есть, сопоставление для B s содержит атрибут order-by? Если нет, тогда у них есть нет порядка в модели данных Hibernate и может быть загружен в любом порядке (скорее всего, в базе данных по умолчанию).

В противном случае я понимаю, что Hibernate должен применять ограничение порядка, когда вы просматриваете pkeys для загрузки. Следовательно, возможно, стоит занять это в списках рассылки в качестве потенциальной ошибки.