3

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?

Guilherme Bernardi
  • 490
  • 1
  • 6
  • 18

2 Answers2

2

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) {
        // ...
    }

}
0

You can use @UniqueElements annotation of Hibernate that you can find on this documentation this is based on equals of some element.

@UniqueElements
private List<Child> childs;
Jonathan JOhx
  • 5,784
  • 2
  • 17
  • 33
  • Sorry, but I think you example doesn't apply to my case, because the objects are different I could have name, age and whatever different and only the email repeats. – Guilherme Bernardi Jan 29 '20 at 21:03
  • So you can `override` `equals` method of `Child` then there you can equals by Id and email as well. This should work based on what you want to do, kind regards. – Jonathan JOhx Jan 29 '20 at 22:17
  • But it would be silently. If you want to throw an error, `overriding equals` is not the best way. – yusuf Oct 28 '20 at 14:00