I have Spring Batch
with a basic chunk:
- Read a CSV file.
- Process it (Transcode some coded value into another ones).
- Write the result into a database.
The problem
In some case, I want insert or update mechnism in my custom ItemWriter
.
Exemple: I can get this 2 lines on my CSV
C006;Test;OK;01/01/1970;1
C006;Test;OK;01/01/1970;5
You can figure out that they are pretty similar except the last column, the strategy will be:
- Check the database if I have a "like so" entity
- if true, update the value with the last item that you get (in our case, the second line with the value 5 in the last column)
What I already did?
In my entity bean, I added a Unique Constraint anotation like so:
@Table(name = "indicator",
uniqueConstraints = { @UniqueConstraint(columnNames =
{ "reference", "type", "status", "date" }) })
I'm sure now that I cannot persist an entity with the same column's data. Then, I created a custom ItemWriter
, and I tried to catch the ConstraintViolationException but it didn't work, I always get an other exeption, even when I tried the parent one.
So do you have any ideas or another way to do it?
I was think about using merge JPA functionality? what do you think about it?
My custom ItemWriter
@Component
public class ImportItemWriter implements ItemWriter<Indicator>{
@Autowired
protected IndicatorDao indicatorDao;
public void write(List<? extends Indicator> items) throws Exception {
for (Indicator item : items) {
Indicator indicator = new Indicator();
indicator.setReference(item.getReference());
indicator.setType(item.getType());
indicator.setStatus(item.getStatus());
indicator.setDueDate(item.getDueDate());
indicator.setValue(item.getValue());
try {
indicatorDao.persist(indicator);
} catch (ConstraintViolationException e) {
// TODO: handle exception
}
}
}
}
Update
Problem Solved
The idea of using Composite PKey
is interesting, but I can't use it because I have to create a composite with 9 keys that's not fair in term of performance. I decided to add function to my DAO
(isDuplicated
) and in my custom ItemWriter
, I just make a simple test:
if `isDuplicated()` then `updateEntity()` else `insertNew()`