使用spring-batch和JPA(由hibernate提供)。
我有一个执行以下操作的步骤:
读者部分是直截了当的,对于作者我使用了JPAItemWriter。在处理阶段,我尝试更新字段,创建新字段并将它们添加到客户端列表并返回客户端,希望编写器将引用的对象和客户端本身写入数据库。
相反,我收到一条错误,指出ID中不存在ID为#123213213的ClientSale。
如何克服这个问题?我应该从处理器(客户端+所有ClientSale)返回对象列表(不同类型)吗? JPAItemWriter可以处理对象列表吗?另一个问题是我将不得不手动更新ClientSale实体中的client_id,而不是将它们添加到列表中并使用hibernate来理解它们之间的关系以及谁指向哪里..
这里的最佳做法是什么?
谢谢!
答案 0 :(得分:1)
好的..这是我最后根据一切所做的事情: 我创建了一个MultiEntityItemWriter,它可以作为项目接收列表(在这种情况下,它会打开它并将所有元素写入委派的ItemWriter。
代码:
public class MultiEntityItemWriter implements ItemWriter<Object>{
private ItemWriter<Object> delegate;
@Override
public void write(List<? extends Object> items) throws Exception {
List<Object> toWrite = new ArrayList<>();
for (Object item : items) {
if (item instanceof Collection<?>) {
toWrite.addAll((Collection<?>)item);
} else {
toWrite.add(item);
}
}
delegate.write(toWrite);
}
public ItemWriter<Object> getDelegate() {
return delegate;
}
public void setDelegate(ItemWriter<Object> delegate) {
this.delegate = delegate;
}
}
现在,我的ItemProcessor可以输出一个列表,其中包含要写入的所有实体,我不需要依赖JPA来了解有更多实体要提交给数据库。
希望它有所帮助...答案 1 :(得分:0)
我认为您正试图一步完成多个步骤。尝试找到一种方法,将工作定义为两步而不是一步。
<batch:job id="MyJob" incrementer="incrementer" job-repository="jobRepository">
<batch:step id="step1" next="step2">
<tasklet >
<chunk reader="reader1"
writer="writer1"
processor="processor1"
commit-interval="10" />
</tasklet>
</batch:step>
<batch:step id="step2">
<tasklet >
<chunk reader="reader2"
writer="writer2"
processor="processor2"
commit-interval="10" />
</tasklet>
</batch:step>
</batch:job>
如果需要,请使用适当的缓存以获得最佳性能。
编辑:
在您的项目编写者中,请确保您使用的是entityManager/session
第一个数据源。同时使用merge
代替persist
来保持你的能量。