Hi, I have a simple value object class:
public class Duration {
private int timeInSec;
protected Duration() {
}
public Duration(int timeInSec) {
if (timeInSec < 0)
throw new IllegalArgumentException("Duration cannot be negative");
this.timeInSec = timeInSec;
}
public Duration(int min, int sec) {
this(min * 60 + sec);
}
public int getTimeInSec() {
return timeInSec;
}
}
And properly registered ValueExtractor class:
@UnwrapByDefault
public class DurationValueExtractor implements ValueExtractor<@ExtractedValue(type = Integer.class) Duration> {
@Override
public void extractValues(Duration originalValue, ValueReceiver receiver) {
receiver.value(null, originalValue != null ? originalValue.getTimeInSec() : null);
}
}
Then I have a class which is validated:
public class SomeClass {
@NotNull
@Positive
private Duration duration;
public Duration getDuration() {
return duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
}
When hibernate validation is done the @Positive constraint is triggered fine for not null value (the value extractor is invoked as it should). But when the field value is null the @NotNull constraint is not triggered and validation passes with no error. It is because
org/hibernate/validator/internal/metadata/core/MetaConstraint.java
omits any default constraint validation when the custom type has the value extractor and value is null:
public boolean validateConstraint(ValidationContext<?> validationContext, ValueContext<?, Object> valueContext) {
boolean success = true;
*if ( valueExtractionPath != null ) {*
Object valueToValidate = valueContext.getCurrentValidatedValue();
*if ( valueToValidate != null ) {*
TypeParameterValueReceiver receiver = new TypeParameterValueReceiver( validationContext, valueContext, valueExtractionPath );
ValueExtractorHelper.extractValues( valueExtractionPath.getValueExtractorDescriptor(), valueToValidate, receiver );
success = receiver.isSuccess();
}
}
*else {*
success = doValidateConstraint( validationContext, valueContext );
}
return success;
}
|