Search code examples
javavalidationexceptiontransactional

Having member variable in Exception class


@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);
}

Here the entity list are formed after reading a excel file and we are adding a logic of validation an excel file. We cannot just validate the excel by itself, we need to read existing database entries before validating.

Now the validator validates the excel where we need to look at existing entities(of some other table) in the database (It is not foreign constraint, some business logic is there) and it creates a list of validationErrorMessages for each invalid entity.

The structure of the Validation class is

ValidationResult {
 boolean isValid;
List<String> errorMessage;
}

Two solution came to my mind

  1. change the signature of save and send ValidationResult(or wrap it into another class). In that case we need to manage rollback ourselves as @Transactional does not rollback work when we do not throw exception

  2. Throw InvalidInputFileException which does have the validationResult in place. (The reason we want to store ValidationResult we need to inform the user about the validation failure).

I am in favour of this approach as it is correct to throw Exception for inconsistent data and secondly @Transactional will work fine and we do not need to manage transactions. However I have not seen member variable in Exception class in code before and is it fine to do that way ?

Now one way I was thinking was in case of ValidationFailure it throws

class InvalidInputFileException extends RuntimeException {
ValidationResult vr;

}

Solution

  • Yes, it's fine. An exception is a class, and it can have member variables and methods like any other class. By the way, a very close example of such an exception is precisely the standard ConstraintValidationException, thrown by the standard Bean Validation framework, which contains a set of constraint violations.

    It's conventional to make exceptions immutable, though: its state is set at creation time and never changes after.