0

I'm trying to create my Size Value Object.

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;

@Getter
@EqualsAndHashCode
@RequiredArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public class Size {

    @Min(value = 1, message = "Size must be greater than zero")
    private final long bytes;

    public static Size ofBytes(long bytes) {
        return new Size(bytes);
    }

    public static Size ofKilobytes(long kilobytes) {
        long bytes = kilobytes * 1024;
        return new Size(bytes);
    }

    public static Size ofMegabytes(long megabytes) {
        long bytes = megabytes * 1024 * 1024;
        return new Size(bytes);
    }

}

As you can see, I'm using javax.validation annotations to add some validation rules to Size.

However, using this approach I'm aware of I need to add some code like this into Size Value Object in order to be able to validate them:

// Create a validator factory
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

So I would need to add a Validator field into my Size Value Object:

@Getter
@EqualsAndHashCode
public class Size {
    private final Validation validation;

    @Positive(message = "Size must be greater than zero")
    private final long bytes;

Here, I feel a bit lost.

Any ideas about how to address it?

My entity class:

@Getter
@Builder(access = AccessLevel.PRIVATE)
@EqualsAndHashCode(of = "checksum")
public class Document {
    private final Name name;
    private final Checksum checksum;
    private final Size size;
    // Rest of the Document class
}
Jordi
  • 20,868
  • 39
  • 149
  • 333

1 Answers1

0

However, using this approach I'm aware of I need to add some code like this into Size Value Object in order to be able to validate them

From what I can learn, this isn't normally code you would have in your object, but rather code that you would have where you construct your object

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

Size invalid = Size.ofBytes(-2);

Set<ConstraintViolation<Size>> violations = validator.validate(invalid);

This is code you might see, for example, in your parser.

Note that the validation is more likely to have value when you are dealing with untrusted input (from the web?) than trusted input (from the database). It can even make sense, in some cases, to have an untrusted size type that is distinct from the trusted size type, so that the java compiler can help you to track that proper validations have been done.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91
  • I wasn't aware of "parse, don't validate" article. As far I've been able to figure out, you suggest me to return a `Either`, or an `Optional` instead of throwing an exception? Could you provide me some helping code? By other side, your comment is related with "what to do when something if wrong" I really appreciate, but, my origianl question was related to how to take advantange of validation framework like jakarta.validation, without adding unnecessary fields on value objects... Any ideas? – Jordi May 19 '23 at 21:41