Как обработать большой набор данных с JPA (или по крайней мере с В спящем режиме)?

Я должен заставить свое веб-приложение работать с действительно огромными наборами данных. В данный момент я получаю или OutOfMemoryException или произвожу, который сгенерирован 1-2 минуты.

Давайте поместим его простой и предположим, что у нас есть 2 таблицы в DB: Worker и WorkLog приблизительно с 1 000 строк в первой и 10 000 000 строк во второй. Последняя таблица имеет несколько полей включая 'workerId' и 'hoursWorked' полей среди других. То, в чем мы нуждаемся:

  1. рассчитайте общие часы работали каждым пользователем;

  2. список периодов работы для каждого пользователя.

Самый простой подход (IMO) для каждой задачи в плоскости SQL:

1)

select Worker.name, sum(hoursWorked) from Worker, WorkLog 
   where Worker.id = WorkLog.workerId 
   group by Worker.name;

//results of this query should be transformed to Multimap<Worker, Long>

2)

select Worker.name, WorkLog.start, WorkLog.hoursWorked from Worker, WorkLog
   where Worker.id = WorkLog.workerId;

//results of this query should be transformed to Multimap<Worker, Period>
//if it was JDBC then it would be vitally 
//to set resultSet.setFetchSize (someSmallNumber), ~100

Так, у меня есть два вопроса:

  1. как реализовать каждый из моих подходов с JPA (или по крайней мере с В спящем режиме);
  2. как Вы решили бы эту проблему (с JPA или Были бы в спящем режиме, конечно)?
18
задан Roman 4 May 2010 в 08:10
поделиться

1 ответ

предположим, что у нас есть 2 таблицы в БД: Worker и WorkLog с примерно 1000 строк в первой и 10 000 000 строк во второй

Для таких больших объемов я бы рекомендовал использовать интерфейс StatelessSession из Hibernate:

В качестве альтернативы Hibernate предоставляет командно-ориентированный API, который можно использовать для потоковой передачи данных в базу данных и из нее базы данных в виде отделенных объектов. У StatelessSession нет никакого контекст персистентности, связанный с ним и не обеспечивает многие из семантики жизненного цикла более высокого уровня. В в частности, сессия без статического состояния не реализует кэш первого уровня и не не взаимодействует ни с кэшем второго уровня, ни с кэшем запросов. Он не реализует транзакционную запись-слежение или автоматической проверки на загрязнения. Операции выполняемые с помощью сеанса без статического состояния никогда не каскадируются на связанные экземпляры. Коллекции игнорируются сеансом без статического состояния сессией. Операции, выполняемые с помощью сеанс без статического состояния, обходят модель событий Hibernate модель событий и перехватчики. Из-за отсутствия кэша первого уровня, сессии без утверждения уязвимы к эффектам смешения данных. Сеанс без статических данных сеанс без статических данных - это абстракция более низкого уровня которая гораздо ближе к базовому JDBC.

StatelessSession session = sessionFactory.openStatelessSession();
Транзакция tx = session.beginTransaction();

ScrollableResults customers = session.getNamedQuery("GetCustomers")
 .scroll(ScrollMode.FORWARD_ONLY);
while (customers.next()) {
 Customer customer = (Customer) customers.get(0);
 customer.updateStuff(...);
 session.update(customer);
}

tx.commit();
session.close();

В этом примере кода, Customer экземпляры, возвращенные запросом немедленно отделяются. Они никогда не не ассоциируются ни с каким контекстом.

Операции insert(), update() и delete(), определяемые операциями StatelessSession, считаются считаются прямыми операциями базы данных операции на уровне строки. Они приводят к немедленное выполнение SQL INSERT, UPDATE или DELETE соответственно. Они имеют различную семантикой, чем save(), saveOrUpdate() и delete() операций, определенных Session интерфейс.

18
ответ дан 30 November 2019 в 08:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: