我有带验证注释的实体,例如@NotNull。我不知道如何在批量持久化操作中阻止容器管理的事务在ConstraintViolationException的情况下回滚,例如:
public void persistAll(List<TheEntity> entities) throws Exception{
for(TheEntity ent : entities){
em.persist(ent);
}
}
在try-catch中包装persist操作无法解决问题,因为即使捕获Constraint异常,该事务也会被标记为回滚(其他任何&#34;已验证的&#34;实体都不会被保留) 。我可以将每个实体的事务隔离开来,但我认为这会对性能产生很大影响(不确定这一点,我使用eclipselink进行批处理JDBC优化)。
我知道ContraintValidationException的行为正如JPA规范要求的那样(标记回滚),但我不确定我是否理解eclipselink批量优化的工作原理(批量操作是否需要)在一次交易中?)。
感谢您的关注。
问候。
编辑:Welp,eclipelink docs声明&#34;批处理写入可以通过在单个事务中而不是单独地将数组INSERT,UPDATE和DELETE语句发送到数据库来提高数据库性能。&#34;,so是的,它需要在一次交易中完成。编辑:我还可以从上下文中注入一个约束验证器,并在persistence.xml上禁用JPA验证器,这样我就可以在JPA PrePersist操作之前验证实体列表。但是,这将影响其他不需要批量操作但仍需要验证的实体。啊!几乎就在那里。
答案 0 :(得分:2)
您可以进行手动验证,只需跳过无效的实体,如下所示:
// 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
}
}