Hibernate.orgCommunity Documentation

Chapter 2. Declaring and validating bean constraints

2.1. Declaring bean constraints
2.1.1. Field-level constraints
2.1.2. Property-level constraints
2.1.3. Class-level constraints
2.1.4. Constraint inheritance
2.1.5. Object graphs
2.2. Validating bean constraints
2.2.1. Obtaining a Validator instance
2.2.2. Validator methods
2.2.3. ConstraintViolation methods
2.3. Built-in constraints
2.3.1. Bean Validation constraints
2.3.2. Additional constraints

In this chapter you will learn how to declare (see Section 2.1, “Declaring bean constraints”) and validate (see Section 2.2, “Validating bean constraints”) bean constraints. Section 2.3, “Built-in constraints” provides an overview of all built-in constraints coming with Hibernate Validator.

If you are interested in applying constraints to method parameters and return values, refer to Chapter 3, Declaring and validating method constraints.

Constraints in Bean Validation are expressed via Java annotations. In this section you will learn how to enhance an object model with these annotations. There are the following three types of bean constraints:

If your model class adheres to the JavaBeans standard, it is also possible to annotate the properties of a bean class instead of its fields. Example 2.2, “Property-level constraints” uses the same entity as in Example 2.1, “Field-level constraints”, however, property level constraints are used.


Note

The property's getter method has to be annotated, not its setter. That way also read-only properties can be constrained which have no setter method.

When using property level constraints property access strategy is used to access the value to be validated, i.e. the validation engine accesses the state via the property accessor method.

Tip

It is recommended to stick either to field or property annotations within one class. It is not recommended to annotate a field and the accompanying getter method as this would cause the field to be validated twice.

The Bean Validation API does not only allow to validate single class instances but also complete object graphs (cascaded validation). To do so, just annotate a field or property representing a reference to another object with @Valid as demonstrated in Example 2.5, “Cascaded validation”.


If an instance of Car is validated, the referenced Person object will be validated as well, as the driver field is annotated with @Valid. Therefore the validation of a Car will fail if the name field of the referenced Person instance is null.

The validation of object graphs is recursive, i.e. if a reference marked for cascaded validation points to an object which itself has properties annotated with @Valid, these references will be followed up by the validation engine as well. The validation engine will ensure that no infinite loops occur during cascaded validation, for example if two objects hold references to each other.

Note that null values are getting ignored during cascaded validation.

Object graph validation also works for collection-typed fields. That means any attributes that

  • are arrays

  • implement java.lang.Iterable (especially Collection, List and Set)

  • implement java.util.Map

can be annotated with @Valid, which will cause each contained element to be validated, when the parent object is validated.


So when validating an instance of the Car class shown in Example 2.6, “Cascaded validation of a collection”, a ConstraintViolation will be created, if any of the Person objects contained in the passengers list has a null name.

The Validator interface is the most important object in Bean Validation. The next section shows how to obtain an Validator instance. Afterwards you'll learn how to use the different methods of the Validator interface.

The Validator interface contains three methods that can be used to either validate entire entities or just single properties of the entity.

All three methods return a Set<ConstraintViolation>. The set is empty, if the validation succeeds. Otherwise a ConstraintViolation instance is added for each violated constraint.

All the validation methods have a var-args parameter which can be used to specify, which validation groups shall be considered when performing the validation. If the parameter is not specified the default validation group (javax.validation.groups.Default) is used. The topic of validation groups is discussed in detail in Chapter 5, Grouping constraints.

Hibernate Validator comprises a basic set of commonly used constraints. These are foremost the constraints defined by the Bean Validation specification (see Table 2.2, “Bean Validation constraints”). Additionally, Hibernate Validator provides useful custom constraints (see Table 2.3, “Custom constraints” and Table 2.4, “Custom country specific constraints”).

Table 2.2, “Bean Validation constraints” shows purpose and supported data types of all constraints specified in the Bean Validation API. All these constraints apply to the field/property level, there are no class-level constraints defined in the Bean Validation specification. If you are using the Hibernate object-relational mapper, some of the constraints are taken into account when creating the DDL for your model (see column "Hibernate metadata impact").

Note

Hibernate Validator allows some constraints to be applied to more data types than required by the Bean Validation specification (e.g. @Max can be applied to Strings). Relying on this feature can impact portability of your application between Bean Validation providers.

Table 2.2. Bean Validation constraints

AnnotationSupported data typesUseHibernate metadata impact
@AssertFalseBoolean, booleanChecks that the annotated element is falseNone
@AssertTrueBoolean, booleanChecks that the annotated element is trueNone
@DecimalMax(value=, inclusive=)BigDecimal, BigInteger, CharSequence, byte, short, int, long and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of NumberChecks whether the annotated value is less than the specified maximum, when inclusive=false. Otherwise whether the value is less than or equal to the specified maximum. The parameter value is the string representation of the max value according to the BigDecimal string representation.None
@DecimalMin(value=, inclusive=)BigDecimal, BigInteger, CharSequence, byte, short, int, long and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of NumberChecks whether the annotated value is larger than the specified minimum, when inclusive=false. Otherwise whether the value is larger than or equal to the specified minimum. The parameter value is the string representation of the min value according to the BigDecimal string representation.None
@Digits(integer=, fraction=)BigDecimal, BigInteger, CharSequence, byte, short, int, long and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of NumberChecks whether the annoted value is a number having up to integer digits and fraction fractional digitsDefines column precision and scale
@Futurejava.util.Date, java.util.Calendar; Additionally supported by HV, if the Joda Time date/time API is on the class path: any implementations of ReadablePartial and ReadableInstantChecks whether the annotated date is in the futureNone
@Max(value=)BigDecimal, BigInteger, byte, short, int, long and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of CharSequence (the numeric value represented by the character sequence is evaluated), any sub-type of NumberChecks whether the annotated value is less than or equal to the specified maximumAdds a check constraint on the column
@Min(value=)BigDecimal, BigInteger, byte, short, int, long and the respective wrappers of the primitive types; Additionally supported by HV: any sub-type of CharSequence (the numeric value represented by the char sequence is evaluated), any sub-type of NumberChecks whether the annotated value is higher than or equal to the specified minimumAdds a check constraint on the column
@NotNullAny typeChecks that the annotated value is not null.Column(s) are not nullable
@NullAny typeChecks that the annotated value is nullNone
@Pastjava.util.Date, java.util.Calendar; Additionally supported by HV, if the Joda Time date/time API is on the class path: any implementations of ReadablePartial and ReadableInstantChecks whether the annotated date is in the pastNone
@Pattern(regex=, flag=)CharSequenceChecks if the annotated string matches the regular expression regex considering the given flag matchNone
@Size(min=, max=)CharSequence, Collection, Map and arraysChecks if the annotated element's size is between min and max (inclusive)Column length will be set to max
@ValidAny non-primitive typePerforms validation recursively on the associated object. If the object is a collection or an array, the elements are validated recursively. If the object is a map, the value elements are validated recursively.None

Note

On top of the parameters indicated in Table 2.2, “Bean Validation constraints” each constraint has the parameters message, groups and payload. This is a requirement of the Bean Validation specification.

In addition to the constraints defined by the Bean Validation API Hibernate Validator provides several useful custom constraints which are listed in Table 2.3, “Custom constraints”. With one exception also these constraints apply to the field/property level, only @ScriptAssert is a class-level constraint.

Table 2.3. Custom constraints

AnnotationSupported data typesUseHibernate metadata impact
@CreditCardNumberCharSequenceChecks that the annotated character sequence passes the Luhn checksum test. Note, this validation aims to check for user mistakes, not credit card validity! See also Anatomy of Credit Card Numbers.None
@EmailCharSequenceChecks whether the specified character sequence is a valid email address. The optional parameters regexp and flags allow to specify an additional regular expression (including regular expression flags) which the email must match.None
@Length(min=, max=)CharSequenceValidates that the annotated character sequence is between min and max includedColumn length will be set to max
@ModCheck(modType=, multiplier=, startIndex=, endIndex=, checkDigitPosition=, ignoreNonDigitCharacters=)CharSequenceChecks that the digits within the annotated character sequence pass the mod 10 or mod 11 checksum algorithm. modType is used to select the modulo type and the multiplier determines the algorithm specific multiplier (see also Luhn algorithm). startIndex and endIndex allow to only run the modulo algorithm on the specified sub-string. checkDigitPosition allows to use an arbitrary digit within the character sequence to be the check digit. If not specified it is assumed that the check digit is part of the specified range. Last but not least, ignoreNonDigitCharacters allows to ignore non digit characters.None
@NotBlankCharSequenceChecks that the annotated character sequence is not null and the trimmed length is greater than 0. The difference to @NotEmpty is that this constraint can only be applied on strings and that trailing whitespaces are ignored.None
@NotEmptyCharSequence, Collection, Map and arraysChecks whether the annotated element is not null nor emptyNone
@Range(min=, max=)BigDecimal, BigInteger, CharSequence, byte, short, int, long and the respective wrappers of the primitive typesChecks whether the annotated value lies between (inclusive) the specified minimum and maximumNone
@SafeHtml(whitelistType=, additionalTags=)CharSequenceChecks whether the annotated value contains potentially malicious fragments such as <script/>. In order to use this constraint, the jsoup library must be part of the class path. With the whitelistType attribute predefined whitelist types can be chosen. You can also specify additional html tags for the whitelist with the additionalTags attribute.None
@ScriptAssert(lang=, script=, alias=)Any typeChecks whether the given script can successfully be evaluated against the annotated element. In order to use this constraint, an implementation of the Java Scripting API as defined by JSR 223 ("Scripting for the JavaTM Platform") must part of the class path. The expressions to be evaluated can be written in any scripting or expression language, for which a JSR 223 compatible engine can be found in the class path.None
@URL(protocol=, host=, port= regexp=, flags=)CharSequenceChecks if the annotated character sequence is a valid URL according to RFC2396. If any of the optional parameters protocol, host or port are specified, the corresponding URL fragments must match the specified values. The optional parameters regexp and flags allow to specify an additional regular expression (including regular expression flags) which the URL must match.None