我有一个@Transactional
方法的服务,它使用JpaRepositiry接口对托管实体进行大量操作,例如更新值和删除实体。
另一方面,在同一个事务方法中,我有一个代码,可以在批处理中创建大量实体
private void methodA() {
......
fetch fieldsToModify and projectsToDelete
......
log.debug("Modifying fields {}", fieldsToModify.size());
issueTrackerFieldRepo.save(fieldsToModify);
log.info("Delete projects {}", projectsToDelete.size());
issueTrackerProjectRepository.delete(projectsToDelete);
log.info("Adding projects {}", projectsToAdd.size());
saveEntitiesInBatch(projectsToAdd);
}
private void saveEntitiesInBatch(List<?> entities) {
for (int i = 0; i < entities.size(); i++) {
Object p = entities.get(i);
log.debug("Creating entity {}", p.getClass().getSimpleName());
entityManager.persist(p);
if (i % batchSize == 0) {
log.debug("Flushing entity manager for {}", i);
entityManager.flush();
entityManager.clear();
}
}
entityManager.flush();
entityManager.clear();
log.debug("Flushing entity manager");
}
其中fieldsToModify
和projectsToDelete
是在同一方法中使用jpa存储库获取然后修改的实体列表。
问题在于,在实体变为“遗忘”之前调用批处理方法saveEntitiesInBatch
时都进行了修改。这也是entityManager.clear()
javadoc所说的。
我希望所有这些代码都在同一个事务中运行。如何使批量插入和jpa存储库实时友好?