mercredi 21 décembre 2016

Need help implementing a custom hibernate validation annotation

So I am trying to create a custom hibernate annotation for checking if the value already exists in the database. This validation is within a Spring Boot Web Application. I am having difficulty writing the annotation in a way that is loosely coupled and reusable. I was using reflection but as stated here, I shouldn't try to access private fields by Field.setAccessible(true). At this point I am stumped and need advice on the best possible way to achieve this. This is quite a complex problem for my skill level which happens to be the first time I have used reflection or created an annotation.

Rough Draft of annotation

@Target( { ElementType.TYPE })
@Retention( RetentionPolicy.RUNTIME)
@Constraint(validatedBy = NotDuplicate.NotDuplicateValidator.class)
@Documented
public @interface NotDuplicate {

    String message() default "A duplicate was found.";

    Class<?> respository();

    String methodName();

    public static class NotDuplicateValidator implements ConstraintValidator<NotDuplicate, Object> {

        @Autowired
        Class<?> respository;

        String methodName;

        public void initialize(NotDuplicate constraintAnnotation) {
            this.respository = constraintAnnotation.respository();
            this.methodName = constraintAnnotation.methodName();
        }


        public boolean isValid(Object object, ConstraintValidatorContext constraintContext) {

            if (object == null) {
                // Bean Validation specification recommends to consider null values as being valid unless annotated @NotNull
                return true;
            }

            try {

                Method method = respository.getMethod(methodName, String.class);
                List<?> resultSet = method.invoke(respository, someFieldValue);
                if (resultSet == null){
                    return false;
                }
                return true;

            } catch (Exception e) {
                System.printStackTrace(e);
                return false;
            }
        }
    }
}

Sample usage of annotation based on vision

@NotDuplicate(respository = UserRepository.class, methodName = "findByEmailAddressIgnoreCase")
private String email;    

The user repository

public interface UserRepository extends CrudRepository<User, Integer> {

    List<User> findByEmailAddressIgnoreCase(String emailAddress);
}





Aucun commentaire:

Enregistrer un commentaire