Home > Back-end >  Hibernate validate object with a list
Hibernate validate object with a list

Time:03-23

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

CodePudding user response:

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.

  • Related