TwoDent
TwoDent

Reputation: 385

HV000030: No validator could be found for constraint (Hibernate Validator)

I was following this tutorial for create a custom validation with multiple parameters, but I get the following exception when executing the @PostMapping method:

HV000030: No validator could be found for constraint 'com.crimsonlogic.anotaciones.TimeRangeConstraints' validating type 'com.crimsonlogic.model.NuevoEvento'. Check configuration for ''

it catches my attention that at the "check configuration for ''" part, does not tell me any kind of information.

NuevoEvento class:

@TimeRangeConstraints.List({
@TimeRangeConstraints(
    fechaEvento="fechaEvento",
    horaInicio="horaInicio",
    horaCulminacion="horaCulminacion"
)
})
public class NuevoEvento {
@NotNull(message="Como se llamara el evento?")
@Size(max=40, message="Titulo invalido")
private String titulo;
@NotNull(message="Seleccione un tipo.")
private String tipoEvento;
private String url;
@NotNull(message="Seleccione la fecha del evento")
private String fechaEvento;
@NotNull(message="A que hora inicia el evento?")
private String horaInicio;
@NotBlank(message="A que hora termina el evento?")
private String horaCulminacion;
@NotNull(message="Seleccione un salon.")
private int salonId;

public NuevoEvento() {}

public String getTitulo() {
    return titulo;
}

public void setTitulo(String titulo) {
    this.titulo = titulo;
}

public String getTipoEvento() {
    return tipoEvento;
}

public void setTipoEvento(String tipoEvento) {
    this.tipoEvento = tipoEvento;
}

public String getUrl() {
    return url;
}

public void setUrl(String url) {
    this.url = url;
}

public String getFechaEvento() {
    return fechaEvento;
}

public void setFechaEvento(String fechaEvento) {
    this.fechaEvento = fechaEvento;
}

public String getHoraInicio() {
    return horaInicio;
}

public void setHoraInicio(String horaInicio) {
    this.horaInicio = horaInicio;
}

public String getHoraCulminacion() {
    return horaCulminacion;
}

public void setHoraCulminacion(String horaCulminacion) {
    this.horaCulminacion = horaCulminacion;
}

public int getSalonId() {
    return salonId;
}

public void setSalon(int salon) {
    this.salonId = salon;
}
}

TimeRangeConstraint annotation:

@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy= TimeRangeValidator.class)
public @interface TimeRangeConstraints {
String fechaEvento();
String horaInicio();
String horaCulminacion();
String message() default "El rango de tiempo establecido no es valido o esta ocupado.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface List {
    TimeRangeConstraints[] value();
}
}

Anyone knows causes of this problem?

Upvotes: 0

Views: 3881

Answers (1)

TwoDent
TwoDent

Reputation: 385

I found the problem.

In my TimeRangeValidator class I had the code as follows:

//HERE WAS THE PROBLEM 
public class TimeRangeValidator implements ConstraintValidator<TimeRangeConstraints,String> { 
//--------------------------------------------------------------------------------->

    private String fechaEvento;
    private String horaInicial;
    private String horaFinal;
    @Autowired
    private UsuarioSalonRepository usuarioSalon;

    @Override
    public void initialize(TimeRangeConstraints constraintAnnotation) {
        this.fechaEvento = constraintAnnotation.fechaEvento();
        this.horaInicial = constraintAnnotation.horaInicio();
        this.horaFinal = constraintAnnotation.horaCulminacion();
    }
    //// MORE AND MOREEE CODE....////

I had to replace the String with Object

public class TimeRangeValidator implements ConstraintValidator<TimeRangeConstraints,Object>

and the problem disappeared.

Deeper explanation for those who did not understand what happened

TimeRangeValidator takes 3 fields from the form to perform the validation logic. The value that was changed previously prevented me from taking the 3 fields of the form due to the following reason:

@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
    Object dt = new BeanWrapperImpl(value).getPropertyValue(fechaEvento);
    Object hInit = new BeanWrapperImpl(value).getPropertyValue(horaInicial);
    Object hFin = new BeanWrapperImpl(value).getPropertyValue(horaFinal);
    SimpleDateFormat form = new SimpleDateFormat("yyyy-MM-dd");
    try {
        Date dia = form.parse(dt.toString().replaceAll("/","-"));
        return TimeUtils.detectOverlappingEvents(usuarioSalon.buscarEvento(dia), 
                hInit.toString().replaceAll("\\s","")+":00", 
                hFin.toString().replaceAll("\\s","")+":00");
    } catch (ParseException e) {
        e.printStackTrace();
        return false;
    }

With the type object I can have the ability (with the help of BeanWrapperImpl) to obtain multiple values of the form to validate them.

Normally, type String (or Integer, whatever) is used to validate a single value of the form.

Upvotes: 2

Related Questions