JPA批处理插入不会释放内存

时间:2019-10-11 20:24:25

标签: java hibernate spring-boot jpa

我正在尝试使用SpringBoot JPA将大约100k项(实体)插入数据库。但是JVM内存不足。

try (Stream<Path> paths = Files.walk(Paths.get(this.folderPath))) {
            paths.filter(Files::isRegularFile).map(Parser::parse).forEach(item -> {
                log.debug("Load trade : " + item.getId());
                itemService.save(item);
            });
        }

其中itemService是使用ItemRepository的服务,而ItemRepository是JPA存储库:

ItemRepository extends JpaRepository<Item, String> {}

在applicateion.yml中,我进行了以下设置,希望这可以避免内存泄漏:

jpa:
    properties:
      hibernate:
        generate_statistics: true
        jdbc.batch_size: 2000

我的理解是,它将每2000个实例执行批量插入,并在每次批量插入后释放内存。但是,我仍然遇到内存不足的异常。在我看来,itemService可以支撑所有交易,因此不执行任何GC。

我是JPA的新手,请问有人可以为避免内存泄漏而做些什么?

赞赏。

2 个答案:

答案 0 :(得分:1)

您必须使用saveAll方法才能使批处理更新生效。

例如

try (Stream<Path> paths = Files.walk(Paths.get(this.folderPath))) {
    List<Path> files = paths
            .filter(Files::isRegularFile)
            .collect(Collectors.toList());

    for (List<Path> batch : Lists.partition(files, 2000)) { // Lists from Guava, batch will be 2000 elements or less.
        List<Item> parsed = batch.stream().map(Parser::parse).collect(Collectors.toList());
        itemService.saveAll(parsed);
    }
}

答案 1 :(得分:0)

为了处理您的批处理,缺少了用于重写批处理插入方式的其他配置:

 jdbc:postgresql://localhost:5432/yourDB?reWriteBatchedInserts=true