@Transactional //Spring transactional
void saveFile(ExcelFile file) {
//Each sheet have different kind of entities and it is an ordered insert and first insert is needed before the second set of inserts
for(each sheet in excel file) {
List<Entity> entityList = convertIntoEntities(sheet);
ValidationResult vr = validateEntities(entityList);
saveEntities(entityList);
}
ValidationResult validateEntities(List<Entity> entityList) {
validator.validate(entityList) // The new validation we need to do before
}
void saveEntities(List<Entity> entityList) {
dao.saveEntities(entityList);
}
这里实体列表是在读取excel文件后形成的,我们正在添加一个验证excel文件的逻辑。我们不能单独验证excel,我们需要在验证之前读取现有的数据库条目。
现在验证器验证我们需要查看数据库中现有实体(某些其他表)的excel(它不是外部约束,有一些业务逻辑),并为每个无效实体创建validationErrorMessages列表
Validation类的结构是
ValidationResult {
boolean isValid;
List<String> errorMessage;
}
我想到了两个解决方案
更改save的签名并发送ValidationResult(或将其包装到另一个类中)。在这种情况下,我们需要自己管理回滚,因为@Transactional在我们不抛出异常时不回滚工作
抛出确实具有validationResult的InvalidInputFileException。 (我们想要存储ValidationResult的原因是我们需要通知用户验证失败)。
我赞成这种方法,因为对不一致的数据抛出异常是正确的,其次@Transactional可以正常工作,我们不需要管理事务。 但是我以前在代码中没有看到Exception类中的成员变量,这样做是否合适?
现在我想的一种方法是在ValidationFailure的情况下抛出
class InvalidInputFileException extends RuntimeException {
ValidationResult vr;
}
答案 0 :(得分:3)
是的,没关系。异常是一个类,它可以像任何其他类一样拥有成员变量和方法。顺便说一下,这种异常的一个非常接近的例子恰好是标准Bean验证框架抛出的标准ConstraintValidationException,它包含一组约束违规。
但是,将异常设为不可变是常规的:它的状态是在创建时设置的,之后永远不会改变。