0

I have User class with list of roles:

@Data
@Table(name = "users")
@Entity
public class User {
    String username;
    String password;
    List<Role>  roles;
}

And the role enum:

public enum Role {
    Admin,User,Manager
}

I need to validate the bean before insert it to DB. The validation expression should look like this:

    long count = user.getRoles().stream().filter(r -> r.equals(Role.Manager)).count();
    !(count > 1);

User cant have more than one manager role, but for other roles its ok to have duplicates; For this i created a custom constraint and a validator for him: Constraint:

@Target({ ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = RoleValidator.class)
public @interface RoleConstraint {

    String message() default "error";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

Validator:

public class RoleValidator implements ConstraintValidator<RoleConstraint, List<Role>> {

    @Override
    public boolean isValid(List<Role> roles, ConstraintValidatorContext context) {
        long count = roles.stream().filter(r -> r.equals(Role.Manager)).count();
        return !(count > 1);
    }
}

but it doesnt work. I also found a solution here but i cant wrap the list in beanList because a lot of other classes depends on this class. Is there other way to solve this problem. Any suggestion is acceptable

1 Answer 1

1

Since you are validating the User, you can make you annotation work with a user. Have the annotation work on classes:

@Target({ ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = RoleValidator.class)
public @interface RoleConstraint {

    String message() default "error";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

Change the validator to work with user:

public class RoleValidator implements ConstraintValidator<RoleConstraint, User> {

    @Override
    public boolean isValid(User user, ConstraintValidatorContext context) {
        long count = user.roles.stream().filter(r -> r.equals(Role.Manager)).count();
        //that's simpler, but is the same as '!(count > 1)'
        return count <= 1;
    }
}

Then apply @RoleConstraint on User class.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.