2012-06-22 7 views
2

В настоящее время я использую пакетные запросы JPA (Eclipse link) для чтения объекта из базы данных. Каждый объект имеет несколько подкатегорий, также отображаемых через JPA.Как ограничить использование памяти пакетными запросами JPA?

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

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

@Entity 
@Table(name = "TBL_ITEMX") 
class ItemX 
{ 
    @OneToMany(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_NO", referencedColumnName = "ID_NO") 
    @BatchFetch(value = BatchFetchType.JOIN) 
    private Collection<SubItem1> subItem1; 

    @OneToMany(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_NO", referencedColumnName = "ID_NO") 
    @BatchFetch(value = BatchFetchType.JOIN) 
    private Collection<SubItem2> subItem2; 

    @OneToMany(fetch = FetchType.EAGER) 
    @JoinColumn(name = "ID_NO", referencedColumnName = "ID_NO") 
    @BatchFetch(value = BatchFetchType.JOIN) 
    private Collection<SubItem3> subItem3; 

    ... getters/setters 
} 

Если я ограничить диапазон запросов с setFirstResult и setMaxResult, например

String qs = "select p from ItemX p"; 
Query qb = em.createQuery(qs); 
qb.setFirstResult(0); 
qb.setMaxResults(100); 

Это утверждает, что я хочу только первые 100 ItemX записей в базе данных, помните, каждый ItemX имеет несколько коллекций. Запрос ограничивает ItemX от 0 до 100. Однако, когда EntityManager обрабатывает коллекцию (ы), он загружает каждую строку базы данных, для каждой из коллекций в память (на клиенте).

Есть ли способ ограничить это поведение, так что пакетный запрос только тянет элементы для каждой коллекции, которая требуется. Или, альтернативно, попросите базу данных оставить результирующий запрос на сервере и предоставить прокручиваемое окно результатов? (Я пробовал прокручиваемые результаты, и это не помогло).

На данный момент я могу обрабатывать запрос, но по мере добавления дополнительных коллекций и данных запрос будет взорвать JVM (и я действительно не думаю, что 64-битная JVM является ответом на это).

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

Благодаря Rich

+0

Это немного странно, но поскольку вы используете batchfetchtype JOIN Я думаю, что eclipselink не может понять, как ограничить запрос/результат соответствующим образом. Как вы пытались с включенным протоколированием (уровень FINE или ниже), чтобы просмотреть запросы? Как вы пробовали с другими типами партий, чем JOIN (IN, являющийся личным фаворитом). Какая база данных вы используете и которая более или менее заблокирована для будущего? – esej

+0

Спасибо за комментарии esej. Я использую Oracle 11g, я бы сказал, что мы заперты для обозримого. У меня есть FINE, и я вижу запросы. Я попробовал IN, но таблицы медленны, а IN ограничено 1000 за пакет. Таким образом, использование IN не обеспечивает большой производительности, однако оно снижает объем памяти. В идеале я бы хотел, чтобы JPA создала временную таблицу соединений из исходного запроса, но я не знаю, чтобы сделать JPA (если это возможно). – Rich

ответ

0

Вы должны использовать партию IN принести тип, если вы хотите использовать его с нумерацией страниц.

+0

Я ранее пробовал пакетный выбор. Это дает мне результаты, которые я хочу, однако производительность была ужасной по сравнению с пакетным соединением. Есть ли у вас какие-либо предложения по увеличению производительности партии? Я пробовал несколько соединений с БД и их допинг не более 1000 на выборку. – Rich

Смежные вопросы