Click here to Skip to main content
15,890,388 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have an issue validating a nested object. What I mean by this is that I have a registration form, where a command object is provided that looks like this

short version:

C#
public class RegistrationObject {
    private User user;
    @NotEmpty
    @Size(min = 5,  message = "{password.size}")
    @Pattern(regexp =
            "^.*(?=.{8,})(?=.*\\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\\d)(?=.*[!@#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$",
            message= "{password.strength}")
    private String repeatPass;

    public RegistrationObject() {
    }

    public RegistrationObject(User user, String repeatPass) {
        this.user = user;
        this.repeatPass = repeatPass;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getRepeatPass() {
        return repeatPass;
    }

    public void setRepeatPass(String repeatPass) {
        this.repeatPass = repeatPass;
    }
}



In my controller I post the object and use @Valid accordingly, it validates the password, but the User object is not being validated. It goes to the service and attempts to be persisted, which throws a validation error. Which is fine, it shows that the constraints work, but validation needs to be happen during form submission.

The question is, why it is not validating the User, and what is a good way to do this kind of validation?

Here are the user, controller method for post and the custom validator


Java
@Entity
@Table(name = "user")
public class User extends BaseEntity implements UserDetails {

    @NotEmpty
    @Size(min = 5, max = 16, message = "{username.size}")
    private String username;
    @NotEmpty
    @Size(min = 5, message = "{password.size}")
    @Pattern(regexp = "^.*(?=.{8,})(?=.*\\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\\d)(?=.*[!@#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$", message= "{password.strength}")
    private String password;
    @NotEmpty
    @Email(message = "{email.valid}")
    private String email;
    @NotEmpty
    @Size(min = 5, max = 16, message = "{firstName.size}")
    private String firstName;
    @NotEmpty
    @Size(min = 5, max = 16, message = "{lastName.size}")
    private String lastName;
    @NotNull
    private int age;
    private boolean enabled;
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "user")
    private Collection<Authorities> authorities = new ArrayList<>();


Controller

Java
@RequestMapping(value = "/signup", method = RequestMethod.POST)
 public String register(@Valid @ModelAttribute("regObject") RegistrationObject regObject, BindingResult result) throws PasswordNotMatchException {
     if (result.hasErrors()) {
         return "registration/signup";
     }
     userService.register(regObject);
     return "redirect:/helloworld/home";
 }


Java
@Component("registrationValidator")
public class RegistrationValidator implements Validator {

    private UserService userService;
    @Autowired
    public RegistrationValidator(UserService userService) {
        this.userService = userService;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return RegistrationObject.class.equals(aClass);
    }

    @Override
    public void validate(Object obj, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "user.password", "password.empty");
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "repeatPass", "password.empty");
        RegistrationObject regObj = (RegistrationObject) obj;
        if (!regObj.getUser().getPassword().equals(regObj.getRepeatPass())) {
            errors.rejectValue("repeatPass", "password.notMatch");
        }
        User user = userService.findByUsername(regObj.getUser().getUsername());
        if (user != null && (user.getUsername().equals(regObj.getUser().getUsername()))) {
            errors.rejectValue("username", "username.unique");
        }
    }
}


What I have tried:

I tried changing the controller method, removing custom validator, which is not ideal and didn't help. Also tried adding @Valid to the registration object user like
@Valid User user

None of them worked.
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900