Reputation: 804
I have entities with validation annotations such as @NotNull. I don't know how to prevent a container managed transaction from rolling back in the case of a ConstraintViolationException in a bulk persist operation such as:
public void persistAll(List<TheEntity> entities) throws Exception{
for(TheEntity ent : entities){
em.persist(ent);
}
}
Wrapping the persist operation in a try-catch would not solve the issue because even by catching the Constraint exception, the transaction would be flagged for rollback (none of the other "validated" entities would be persisted). I could isolate the transaction per entity to persist, but I think this will impact a lot on performance (not sure about this, I'm using eclipselink with batch JDBC optimization).
I know that the behavior of the ContraintValidationException is working as the JPA spec mandates (flagging rollback), but I'm not sure if I'm understanding how the eclipselink batch optimization works (does the bulk opeations need to be in a single transaction?).
Thanks for the interest.
Regards.
EDIT: Welp, eclipelink docs state that "Batch writing can improve database performance by sending groups of INSERT, UPDATE, and DELETE statements to the database in a single transaction, rather than individually.", so yes, it needs to be done in a single transaction.
EDIT: I could also inject a constraint validator from the context and disable the JPA validator on persistence.xml, so I can validate the entity list prior the JPA PrePersist operation. However, this will affect other entities that won't need bulk operations on them but still need validation. Ahh! almost there.
Upvotes: 1
Views: 742
Reputation: 18030
You can do manual validation and just skip the entities that are not valid, like this:
// in the class inject validator
@Resource
Validator validator;
...
for(TheEntity ent : entities){
if( validator.validate(ent).size() == 0) {
// valid - persist
em.persist(ent);
} else {
// invalid - skip
}
}
Upvotes: 2