Java 处理对象的创建,该对象有一个子对象(~可能是1000000个或更多实体的集合)

Java 处理对象的创建,该对象有一个子对象(~可能是1000000个或更多实体的集合),java,oracle,jpa,eclipselink,spring-batch,Java,Oracle,Jpa,Eclipselink,Spring Batch,我在处理一个对象的创建或修改时遇到了一些问题,该对象在批处理中有一个子对象(一个实体集合(可能是1000000或更多)) 开始时,我尝试直接创建对象: entite.getEntiteManager(session).createEntite(entite); 但是,以下情况除外: maximum open cursors exceeded was thrown. 因此,我尝试了第二种方法:我首先创建父亲,然后创建250个孩子,我影响父亲对他们的引用,而不是我承诺。这就是现在的工作 问题是:

我在处理一个对象的创建或修改时遇到了一些问题,该对象在批处理中有一个子对象(一个实体集合(可能是1000000或更多))

开始时,我尝试直接创建对象:

entite.getEntiteManager(session).createEntite(entite);
但是,以下情况除外:

maximum open cursors exceeded was thrown.
因此,我尝试了第二种方法:我首先创建父亲,然后创建250个孩子,我影响父亲对他们的引用,而不是我承诺。这就是现在的工作

问题是:如果在创建子对象的过程中出现了一些问题,那么它只回滚它所面临的问题列表。其他人已经承诺了


在这种情况下,SpringBatch对我是否有用。他是否处理了这个问题。

Spring批处理“分块”概念将支持您所描述的重试和失败场景。也就是说,您已经创建了500条记录,并且出现了一个故障,您不希望在重新启动时丢失已经拥有的记录

此类作业的简单配置可能如下所示:

<batch:job id="entityCreationJob">
    <batch:step id="entityCreationJob.step1">
        <batch:tasklet>
            <batch:chunk reader="entityReader" writer="entityWriter" commit-interval="250"/>
        </batch:tasklet>
    </batch:step>
</batch:job>

这个简单的配置将执行以下操作:; -“每行”读取/创建一条记录
(entity.getEntityManager(session.createEntity(e))
-“提交”250个记录块中的记录(由提交间隔设置)

如果您有一个提交间隔为250的失败(比如记录1190),那么您只会“丢失”190条记录的工作。以前的1000个已提交到数据库。当应用程序重新启动时,它将在1001记录处拾取并继续,在250个记录块中提交


为了充分利用提交/重试组件,我建议您使用
JpaItemWriter
JpaTransactionManager
或JTA事务管理器。

这就是我讨厌ORMs的原因。它们有自己的角色,但它们不是为批量更新数百万行而设计的。你将永远把你的头发拔出来,试图强迫自己适合这个。编写存储过程或其他SQL调用来执行本机SQL更新。感谢您的回复。我想做一种临时表来存储信息,直到我完成,而不是提交到真正的表。不要使用ORM进行批处理。这就像用勺子挖巴拿马运河。关于使用临时工作台-是的!对对如果您在关系数据库中工作,最好考虑表、联接和视图,即关系操作。这就是数据库优化的目的。添加一个ORM和一堆对象(好东西,对象-不会说一句反对它们的话-我的一些最好的朋友是对象:-)只会堆积在一堆层上,这些层在批处理环境中毫无用处(IMO)。表、视图、联接-这就是问题所在!如果集合将包含一百万个实体,那么对象模型可能不应该映射父->子关系。您始终可以直接查询子项,如果需要,可以使用光标或分页,并且只映射子项->父项关系。其次,EclipseLink允许批处理。调用em.flush()和em.clear()来管理内存。查看和查找