spring-bootjavax.validation

Is there an annotation for java validate if the value of a field in a List of Objects is duplicated?


I have a List of Objects and each Object have an email, I'd like to validate if the email is duplicated in this list.

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
Father create(@PathVariable String id,
        @Valid @RequestBody Father father) {
   ...
}

Father will have a list of child:

private List<Child> childs;

Each child will have an email:

public class Child {
  ...

  @NotEmpty
  private String email;

  ...
}

I'd like to validate if for example there is a request body with 2 child with the same email.

Is it possible or only validating after receive and process the payload?


Solution

  • Edited

    For validating the child emails list, you can create a custom validation.

    I coded a custom validation as follows

    1- Create annotation named ChildEmailValidation

    @Documented
    @Constraint(validatedBy = ChildEmailValidator.class)
    @Target( { ElementType.METHOD, ElementType.FIELD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ChildEmailValidation {
    
        String message() default "Duplicate Email";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    
    }
    

    2- Create a validator for ChildEmailValidation

    In this part, you can write your custom business for validation. (You can write your algorithm)

        public class ChildEmailValidator implements ConstraintValidator<ChildEmailValidation, List<Child>> {
    
        @Override
        public void initialize(ChildEmailValidation constraintAnnotation) {
    
        }
    
        @Override
        public boolean isValid(List<Child> childList, ConstraintValidatorContext constraintValidatorContext) {
    
            //Create empty mailList
            List<String> mailList = new ArrayList<>();
    
            //Iterate on childList
            childList.forEach(child -> {
    
                //Checks if the mailList has the child's email
                if (mailList.contains(child.getMail())) {
    
                      //Found Duplicate email
                      throw new DuplicateEmailException();
    
                }
    
                //Add the child's email to mailList (If duplicate email is not found)
                mailList.add(child.getMail());
    
            });
    
    
            //There is no duplicate email
            return true;
          }
    
        }
    

    3- Add @ChildEmailValidation in Father class

    public class Father {
    
        List<Child> child;
    
        @ChildEmailValidation
        public List<Child> getChild() {
            return child;
        }
    
        public void setChild(List<Child> child) {
            this.child = child;
        }
    } 
    

    4- Put @Valid on fatherDto in the controller

    @RestController
    @RequestMapping(value = "/test/", method = RequestMethod.POST)
    public class TestController {
    
        @RequestMapping(value = "/test")
        public GenericResponse getFamily(@RequestBody @Valid Father fatherDto) {
            // ...
        }
    
    }