Я новичок в Hibernate. У меня есть следующий код, который сохраняет большое количество (скажем, 10 КБ) строк из List<String>:

@Override
@Transactional(readOnly = false)
public void createParticipantsAccounts(long studyId, List<String> subjectIds) throws Exception {
    StudyT study = studyDAO.getStudyByStudyId(studyId);
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    for(String subjectId: subjectIds) {  // LOOP with saveAndFlush() for each
        // ...
        user.setRoleTypeId(4);
        user.setActiveFlag("Y");
        user.setCreatedBy(auth.getPrincipal().toString().toLowerCase());
        user.setCreatedDate(new Date());
        List<StudyParticipantsT> participants = new ArrayList<StudyParticipantsT>();
        StudyParticipantsT sp = new StudyParticipantsT();
        sp.setStudyT(study);
        sp.setUsersT(user);
        sp.setSubjectId(subjectId);
        sp.setLocked("N");
        sp.setCreatedBy(auth.getPrincipal().toString().toLowerCase());
        sp.setCreatedDate(new Date());
        participants.add(sp);
        user.setStudyParticipantsTs(participants);
        userDAO.saveAndFlush(user);
    }
   }
}

Но эта операция занимает слишком много времени, около 5-10 мин. на 10К рядов. Как правильно это исправить? Мне действительно нужно переписать все это с помощью пакетной вставки или есть что-то простое, что я могу настроить?

ПРИМЕЧАНИЕ . Я также пробовал userDAO.save() без промывки и userDAO.flush() в конце вне цикла for. Но это не помогло, такая же плохая производительность.

0
gene b. 20 Окт 2019 в 23:12

1 ответ

Лучший ответ

Мы решили это. Пакетные вставки выполняются с помощью saveAll . Мы определяем размер пакета, скажем 1000, и saveAll список, а затем сбрасываем. Если в конце (краевое условие) еще и экономим. Это резко ускорило все вставки.

    int batchSize = 1000;

    // List for Batch-Inserts
    List<UsersT> batchInsertUsers = new ArrayList<UsersT>();

    for(int i = 0; i < subjectIds.size(); i++) {

        String subjectId = subjectIds.get(i);   

        UsersT user = new UsersT();
        // Fill out the object here...
        // ...

        // Add to Batch-Insert List; if list size ready for batch-insert, or if at the end of all subjectIds, do Batch-Insert saveAll() and clear the list
        batchInsertUsers.add(user);
        if (batchInsertUsers.size() == maxBatchSize || i == subjectIds.size() - 1) {
            userDAO.saveAll(batchInsertUsers);
            // Reset list
            batchInsertUsers.clear();
        }

    }
2
gene b. 22 Окт 2019 в 19:59