I had a similar problem with writing multiple rows to the database. Since the job step creates a list of your items, how can you return a list from a process to a writer? This will create a list of lists, and the doWrite method in Writer is not configured to handle this script.
I am using 1.2.0 spring-boot-starter-parent (which gives me spring -core 4.1.3) along with sleeping (4.3.7). In my case, I have a โreceivableโ, and for every 1 receivable I read from the csv file, I may need to update or insert many receivables into my table. I also use HibernateItemWriter.
My solution was to extend HibernateItemWriter. The sessionFactory field is private, so I pass it through the constructor, as well as using setter (to accommodate existing code). Thus, my source code (which works just fine for one โreceivableโ) initially looked like this:
@Bean public ItemWriter<Receivable> recivableWriter() { HibernateItemWriter<Receivable> hibernateItemWriter = new HibernateItemWriter<Receivable>(){{ setSessionFactory(sessionFactory); }}; return hibernateItemWriter; }
After expanding HibernateItemWriter and changing my processor to return the list, my code changed to:
@Bean public ItemWriter<List<Receivable>> receivableWriter() { HibernateListItemWriter<List<Receivable>> hibernateItemWriter = new HibernateListItemWriter<List<Receivable>>(this.sessionFactory){{ setSessionFactory(sessionFactory); }}; return hibernateItemWriter; }
And my extended class looks like this (I can clear it, but this is my initial pass. I also want sessionFactory and clearSession fields not to be private)
package com.work; import java.util.ArrayList; import java.util.List; import org.hibernate.SessionFactory; public class HibernateListItemWriter<Receivable> extends org.springframework.batch.item.database.HibernateItemWriter<Receivable> { public HibernateListItemWriter(SessionFactory sessionFactory) { super(); this.sessionFactory = sessionFactory; } private SessionFactory sessionFactory; private boolean clearSession = true; @Override public void write(List items) { List<Receivable> unwrappedItems = new ArrayList<Receivable>(); List<List<Receivable>> wrappedItems = (List<List<Receivable>>)items; for (List<Receivable> singleList: wrappedItems) { unwrappedItems.addAll(singleList); } doWrite(sessionFactory, unwrappedItems); sessionFactory.getCurrentSession().flush(); if(clearSession) { sessionFactory.getCurrentSession().clear(); } } }
A big scream at grepcode.com to make life easier.
Mattc
source share