jakartaee / validation

Jakarta Validation
http://beanvalidation.org
Apache License 2.0
127 stars 54 forks source link

Support the Valid annotation on parameterized types to an interface class #186

Open njr-11 opened 1 year ago

njr-11 commented 1 year ago

Please add this in Jakarta EE 11. It is needed by Jakarta Data.

When performing method validation on methods that came from an interface and you don't control the interface yourself, it is currently not possible to request cascading validation on the parameters and return value of the method. The proposal is to support annotating type parameter(s) with @Valid when inheriting from the interface in order to request that cascading validation be automatically performed during method validation for parameters and return values of the annotated type.

For example, Jakarta Data has a built-in interface CrudRepository, which defines a very commonly used save operation, which is where validation of constraints on the passed-in entity parameter is often desired. Jakarta Data repositories that the user defines inherit from this interface, for example,

@Repository
public interface School extends CrudRepository<Student, Integer> {
... // inherits save(Student) operation from CrudRepository
}

@Entity
public class Student {
   @Email
   public String email;
   @NotBlank
   public String name;
   @Id
   public int studentId;
}

The user who defines this class, would like to annotate the Student parameter with @Valid, as follows:

@Repository
public interface School extends CrudRepository<@Valid Student, Integer> {
... // inherits save(Student) operation from CrudRepository
}

which we would like to see cause the constraints of the Student class to be validated when a Student object is supplied to:

    school.save(student);

Mailing list discussion: https://www.eclipse.org/lists/bean-validation-dev/msg00029.html

njr-11 commented 1 year ago

I've also observed that constraints on type variables, such as @Positive below, do not seem to have the effect of applying to method parameters of that type, so this pattern might be consistently not working,

@Repository
public interface School extends CrudRepository<@Valid Student, @Positive Integer> {
    Optional<Student> findByStudentId(Integer studentId);

    ... // inherits save(Student) operation from CrudRepository
}