Hibernate Validator is a very precise framework written in the hibernate umbrella of frameworks. Using the inbuilt validators should solve most of your column constraints. However, if you have Decimal types (Float, Double of BigDecimal), there is no inbuilt validator to validate both the precision and scale. Also, I’ve stopped using Doubles and Floats in bargain with BigDecimal as:-
1) BigDecimal has better control over math functions
2) It generates the correct column type, is Number(precison, scale) in most databases when used with hbm2ddl Tool
I’ve written two classes for validating the range (minimum and maximum) of BigDecimal types, extending HibernateValidator. It’s as good as annotating like this, for your property
@BigDecimalRange(minPrecision=0, maxPrecision=13, scale=2)
public BigDecimal getFoo() {
return this.foo;
}
BigDecimalRange
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.hibernate.validator.ValidatorClass;
/**
* The annotated element has to be in the appropriate range. Apply on BigDecimal values.
*/
@Documented
@ValidatorClass(BigDecimalRangeValidator.class)
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface BigDecimalRange {
long minPrecision() default Long.MIN_VALUE;
long maxPrecision() default Long.MAX_VALUE;
int scale() default 0;
String message() default "precision must be in the range of {minPrecision} to {maxPrecision} with scale<= {scale}";
}
BigDecimalRangeValidator
import java.io.Serializable;
import java.math.BigDecimal;
import org.hibernate.validator.Validator;
/**
* The value has to be in a defined range with precision & scale
*/
public class BigDecimalRangeValidator implements Validator<bigdecimalrange>, Serializable {;
private long minPrecision;
private long maxPrecision;
private int scale;
public void initialize(BigDecimalRange parameters) {
minPrecision = parameters.minPrecision();
maxPrecision = parameters.maxPrecision();
scale = parameters.scale();
}
public boolean isValid(Object value) {
if ( value == null ) return true;
else if ( value instanceof BigDecimal ) {
int _precision = ((BigDecimal)value).precision();
int _scale = ((BigDecimal)value).scale();
return (_precision >= minPrecision && _precision <= maxPrecision && _scale <= scale);
}
else {
return false;
}
}
}
Post a Comment