0

I am trying to implement Javax Validation on Immutable objects, but I only get it working by renaming every variable with prefix "get". It is possible to make it work without that "get" ?

    @Value.Immutable
    public interface Entity {
        @Min(19)
        int getAge();

        @NotBlank
        @Size(min = 10)
        String getName();

    }

my controller:

@PostMapping("/entity/")
public ResponseEntity post2(@RequestBody @Valid ImmutableEntity entity) {


    return  new ResponseEntity<Object>("", HttpStatus.OK);
}
John
  • 1,697
  • 4
  • 27
  • 53

1 Answers1

2

If I understand @Value.Immutable correctly, you are supposed to annotate it on a class or interface with the methods representing the to-be-generated fields. Example:

@Value.Immutable
public interface Entity {
    int getAge();
    String getName();
}

This would mean that the following would be generated:

@Generated(from = "Entity", generator = "Immutables")
public final class ImmutableEntity implements Entity {
  private final int age;
  private final String name;

  private ImmutableEntity(int age, String name) {
    this.age = age;
    this.name = name;
  }

  @Override
  public int getAge() {
    return age;
  }

  @Override
  public String getName() {
    return name;
  }

  (...)
}

If you do not follow the getXXXXX() pattern you will get a different generated class as follows:

@Value.Immutable
public interface Entity {
    int age();
    String name();
}

With this one you would get the following generated class:

@Generated(from = "Entity", generator = "Immutables")
public final class ImmutableEntity implements Entity {
  private final int age;
  private final String name;

  private ImmutableEntity(int age, String name) {
    this.age = age;
    this.name = name;
  }

  @Override
  public int age() {
    return age;
  }

  @Override
  public String name() {
    return name;
  }

  (...)
}

Mind the differences. In the first one, you have normal getters, in the second one you have "getters" without the prefix get in the method name. Javax Validation uses normal getters to get the data so that it can be validated. In the second generated class, you getters do not follow the usual naming convention, and thus Javax Validation does not work.

João Dias
  • 16,277
  • 6
  • 33
  • 45
  • thank you, but i've seen some examples that use validation without the get prefix. – John Sep 28 '21 at 17:46
  • Sure, but the issue is not the Validation, it is the `@Value.Immutable` itself. If you don't use `getXXXX` do you get the corresponding attributes in the generated implementation class? I guess not. – João Dias Sep 28 '21 at 17:56
  • https://immutables.github.io/ on the official documentation there are some examples without get – John Sep 28 '21 at 19:09
  • Please check my answer, I've edited it. – João Dias Sep 28 '21 at 23:20
  • Thank you for your explanation, do you know if there is a way with spring validator to change this Javax validation prefix? – John Sep 29 '21 at 09:37
  • 1
    It does not seem possible. According to the [reference documentation](https://beanvalidation.org/1.0/spec/#constraintdeclarationvalidationprocess-requirements-property): "It is required that the class follows the method signature conventions for JavaBeans read properties (...) for every constraint property of type T, there is a getter method, get. For boolean properties, is is an alternative name for the getter method.". – João Dias Sep 29 '21 at 21:42