我遇到了一个Spring Batch作业的问题,该作业需要读取一个大型CSV文件(几百万条记录)并将这些记录保存到数据库中。作业使用0xff...ff
来读取CSV,使用-1
来将已读取和已处理的记录写入数据库。问题在于,FlatFileItemReader
在将另一批项目刷新到数据库后并没有清除持久性上下文,并且作业最终以JpaItemWriter
结尾。
我已经通过扩展JpaItemWriter
并重写了write方法来解决了这个问题,以便在写完一堆之后调用OutOfMemoryError
,但是我想知道Spring Batch是否已经解决了这个问题以及问题出在工作配置中。如何正确解决这个问题?
我的解决方案:
JpaItemWriter
您可以在write方法中看到添加的EntityManager.clear()
。
作业配置:
class ClearingJpaItemWriter<T> extends JpaItemWriter<T> {
private EntityManagerFactory entityManagerFactory;
@Override
public void write(List<? extends T> items) {
super.write(items);
EntityManager entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory);
if (entityManager == null) {
throw new DataAccessResourceFailureException("Unable to obtain a transactional EntityManager");
}
entityManager.clear();
}
@Override
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
super.setEntityManagerFactory(entityManagerFactory);
this.entityManagerFactory = entityManagerFactory;
}
}
答案 0 :(得分:2)
这是一个正确的观点。 JpaItemWriter
(和HibernateItemWriter
)用于清除持久性上下文,但已在BATCH-1635中删除(此处the commit已将其删除)。但是,已通过HibernateItemWriter
参数(请参见此BATCH-1759)在commit的clearSession
中的JpaItemWriter
中对其进行了重新添加和配置,但未在JpaItemWriter
中对其进行配置
因此,我建议针对Spring Batch打开一个问题,向HibernateItemWriter
添加相同的选项,以便在编写项目后清除持久性上下文(这与GET city_offices/_search
{
"size" : 10,
"query": {
"term" : { "office_type" : "secondary" }
},
"aggs": {
"citizens": {
"nested": {
"path": "citizens"
},
"aggs": {
"inner": {
"filter": {
"term": { "citizens.age": "40" }
} ,
"aggs": {
"occupations": {
"nested": {
"path": "citizens.pets"
},
"aggs": {
"inner_pets": {
"filter": {
"term": { "citizens.pets.name": "Casper" }
} ,
"aggs": {
"lll": {
"reverse_nested": {
"path": "citizens"
},
"aggs": {
"xxx": {
"terms": {
"field": "citizens.occupation",
"size": 10
}
}
}
}
}
}
}
}
}
}
}
}
}
}
一致)
也就是说,要回答您的问题,您确实可以像以前一样使用自定义编写器清除持久性上下文。
希望这会有所帮助。