Пакетное чтение из БД с помощью Hibernate

Рейтинг: 0Ответов: 1Опубликовано: 16.04.2023

Я использую CriteriaBuilder для вычитывая всех данных из БД. Когда число записей доходит до 2 млн начинаются торможения.

EntityManagerFactory entityManagerFactory1 = entityManagerFactory.getEntityManagerFactory();
SessionFactory sessionFactory = entityManagerFactory1.unwrap(SessionFactory.class);
Session session = sessionFactory.openSession();

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<BIS_DATA> critQuery = builder.createQuery(BIS_DATA.class);

critQuery.select(critQuery.from(BIS_DATA.class));

Query<BIS_DATA> query = session.createQuery(critQuery);
List<BIS_DATA> results = query.getResultList();

мне интересно есть ли аналог в Hibernate из JDBC Statement .setFetchSize(fetchSize); и как отключить запись данных в кэш при чтении?

Ответы

▲ 1

по обоим вопросам ответ: да

  1. размер JDBC fetchSize задается через org.hibernate.Query#setFetchSize: тут нужно или кастануть Query<BIS_DATA> query к org.hibernate.Query или выполнить javax.persistence.Query#unwrap - в JPA API такой возможности, увы, не предусмотрено, а в конкретной реализации - без проблем. Хотя, с другой стороны потенциальный профит от этого не очевиден поскольку в конце концов на выходе оказывается список, а не курсор/стрим (т.е. если БД - Oracle, то выигрыша не будет никакого, потому что там и так по умолчанию fetch size указан довольно разумный, в случае PostgreSQL можно по используемой памяти в каком-то моменте выйграть в 2 раза).

  2. чтобы сущности из результата запроса не оседали в персистентном контексте, можно сказать хиберу, что мы не собирается модифицировать полученные данные, т.е.: org.hibernate.Query#setReadOnly