From hibernate-commits at lists.jboss.org Wed Sep 2 11:47:48 2009 Content-Type: multipart/mixed; boundary="===============2445757126768062887==" MIME-Version: 1.0 From: hibernate-commits at lists.jboss.org To: hibernate-commits at lists.jboss.org Subject: [hibernate-commits] Hibernate SVN: r17469 - validator/trunk/hibernate-validator/src/main/docbook/en-US/modules. Date: Wed, 02 Sep 2009 11:47:48 -0400 Message-ID: <200909021547.n82Flm9I007335@svn01.web.mwc.hst.phx2.redhat.com> --===============2445757126768062887== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: hardy.ferentschik Date: 2009-09-02 11:47:47 -0400 (Wed, 02 Sep 2009) New Revision: 17469 Modified: validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/custo= mconstraints.xml validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defin= econstraints.xml validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/getti= ngstarted.xml validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/using= validator.xml Log: HV-220 Modified: validator/trunk/hibernate-validator/src/main/docbook/en-US/module= s/customconstraints.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/cust= omconstraints.xml 2009-09-02 13:24:17 UTC (rev 17468) +++ validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/cust= omconstraints.xml 2009-09-02 15:47:47 UTC (rev 17469) @@ -25,7 +25,7 @@ - Custom constraints + Creating custom constraints = Though the Bean Validation API defines a whole bunch of standard constraint annotations such as @NotNull, @@ -251,10 +251,10 @@ Using the constraint = Now that our first custom constraint is completed, we can use = it - in the Car class from the Getting started chapter = to - specify that the licensePlate field shall only - contain upper-case strings: + in the Car class from the chapter to specify that the + licensePlate field shall only contain upper-case + strings: = package com.mycompany; = Modified: validator/trunk/hibernate-validator/src/main/docbook/en-US/module= s/defineconstraints.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defi= neconstraints.xml 2009-09-02 13:24:17 UTC (rev 17468) +++ validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defi= neconstraints.xml 2009-09-02 15:47:47 UTC (rev 17469) @@ -1,4 +1,4 @@ - + - - - + Defining constraints = @@ -38,7 +37,7 @@ element. = -
+
Built in constraints = Hibernate Validator comes with some built-in constraints, which @@ -491,4 +490,4 @@ The name property will be checked for nullity when the Dog bean = is validated.
- \ No newline at end of file + Modified: validator/trunk/hibernate-validator/src/main/docbook/en-US/module= s/gettingstarted.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gett= ingstarted.xml 2009-09-02 13:24:17 UTC (rev 17468) +++ validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gett= ingstarted.xml 2009-09-02 15:47:47 UTC (rev 17469) @@ -105,7 +105,7 @@ and Intellij have great built-in Maven support. = - + Class Car annotated with constraints = package com.mycompany; @@ -127,7 +127,6 @@ private int seatCount; = public Car(String manufacturer, String licencePlate, int seatCount) { - this.manufacturer =3D manufacturer; this.licensePlate =3D licencePlate; this.seatCount =3D seatCount; @@ -188,7 +187,6 @@ = @Test public void manufacturerIsNull() { - Car car =3D new Car(null, "DD-AB-123", 4); = Set<ConstraintViolation<Car>> constraintViolations =3D @@ -200,7 +198,6 @@ = @Test public void licensePlateTooShort() { - Car car =3D new Car("Morris", "D", 4); = Set<ConstraintViolation<Car>> constraintViolations =3D = @@ -212,7 +209,6 @@ = @Test public void seatCountTooLow() { - Car car =3D new Car("Morris", "DD-AB-123", 1); = Set<ConstraintViolation<Car>> constraintViolations =3D @@ -224,7 +220,6 @@ = @Test public void carIsValid() { - Car car =3D new Car("Morris", "DD-AB-123", 2); = Set<ConstraintViolation<Car>> constraintViolations =3D Modified: validator/trunk/hibernate-validator/src/main/docbook/en-US/module= s/usingvalidator.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usin= gvalidator.xml 2009-09-02 13:24:17 UTC (rev 17468) +++ validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usin= gvalidator.xml 2009-09-02 15:47:47 UTC (rev 17469) @@ -25,7 +25,7 @@ - Basic validation + Validation step by step = In this chapter we will see in more detail how to use Bean Validat= ion to validate constraints for a given entity model. We will also learn whi= ch @@ -34,7 +34,7 @@ to add constraints to an entity. =
- Annotating your model + Defining constraints = Constraints in Bean Validation are expressed via Java annotation= s. In this section we show how to annotate an object model with these @@ -42,30 +42,83 @@ constraint annotations - class-, field- and property-level annotations. = - - Not all constraints can be placed on any of these levels. In - fact all the default constraints defined by Bean Validation cannot= be - places at class level. The java.lang.annotation.Target annotation - placed on the constraint annotation itself determines on which - elements a constraint can be placed. See also - + + Not all constraints can be placed on any of these levels. In f= act + all the default constraints defined by Bean Validation cannot be pla= ces + at class level. The java.lang.annotation.Target annotation placed on= the + constraint annotation itself determines on which elements a constrai= nt + can be placed. See also + =
Class-level - annotations + constraints = - TODO + When a constraint annotation is placed on class level the class + instance itself passed to the + ConstraintValidator. Class level constraints = are + useful if it is necessary to inspect more than a single property of = the + class to validate it or if a correlation between different state + variables has to be evaluated. In the following example we add the + properties horsePower and + kiloWatt to the class Car. + We also add the constraint ValidCar to the class itself. We will lat= er + see how we can actually create this custom constraint (see ). For now we can just ass= ume + that this constraints will for example ensure that the value for + kiloWatt is 0.7456 * + horsePower. + + + Class Car with added horsePower and killoWatt + properties + + package com.mycompany; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +@ValidCar +public class Car { + + @NotNull + private String manufacturer; + + @NotNull + @Size(min =3D 2, max =3D 14) + private String licensePlate; + + @Min(2) + private int seatCount; + + private int horsePower; + + private double kiloWatt; + = + public Car(String manufacturer, String licencePlate, int seatCount) { + this.manufacturer =3D manufacturer; + this.licensePlate =3D licencePlate; + this.seatCount =3D seatCount; + } + + //getters and setters ... +} +
=
- Field level annotations + Field-level constraints = - One way for expressing constraints is to annotate the fields o= f a - class with constraint annotations. The following listing shows a sim= ple - example: + Constraints can also be expressed by annotating a field of a + class. The following listing shows a simple example: = - package com.mycompany; + + Example for field level constraints = + package com.mycompany; + import javax.validation.constraints.NotNull; = public class Car { @@ -74,24 +127,32 @@ private String manufacturer; = public Car(String manufacturer) { - this.manufacturer =3D manufacturer; } } + + + When using field level constraints field access strategy is us= ed + to access the value to be value. This means the bean validation prov= ider + accesses the instance variable directly.
=
- Property level annotations + Property-level constraints = If your model class adheres to the JavaBeans - standard (meaning basically, there are getter and setter methods for= the - properties of the class), it is also possible to annotate the proper= ties - of a bean class instead of its fields. Note that the property's gett= er - method has to be annotated, not its setter method: + standard, it is also possible to annotate the properties of a bean c= lass + instead of its fields. + The property's getter method has to be annotated, not its + setter. + = - package com.mycompany; + + Example for property level constraints = + package com.mycompany; + import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotNull; = @@ -100,8 +161,7 @@ private String manufacturer; = private boolean isRegistered; - = - = + = public Car(String manufacturer, boolean isRegistered) { super(); this.manufacturer =3D manufacturer; @@ -126,20 +186,21 @@ this.isRegistered =3D isRegistered; } } + = - Generally it is considered a good practice to stick either with - field or with property annotation within one mo= del - class for the sake of readability. It is not recommended to annotate= a - field and the accompanying getter method as this - would cause the field to be validated twice. + When using property level constraints property access strategy= is + used to access the value to be validated. This means the bean valida= tion + provider accesses the state via the property accessor method. = - TODO: Make it explcit that where the difference lies between f= iled - and property level annotations. Depending where I place the annotati= on - the value to be validated gets accessed in different ways! + Generally it is recommended to stick either to field + or property annotation within one class. It is = not + recommended to annotate a field and the + accompanying getter method as this would cause the field to be valid= ated + twice.
=
- Annotated interfaces and super-classes + Constraint inheritance = When validating an object that implements an interface or exte= nds another class, all constraint annotations on the implemented interfa= ce @@ -147,33 +208,11 @@ on the validated object itself. To make things clearer let's have a = look at the following example: = - //class Car -package com.mycompany; + + Example for constraint inheritance using RentalCar = -import javax.validation.constraints.NotNull; + package com.mycompany; = -public class Car { - - private String manufacturer; - = - public Car(String manufacturer) { - this.manufacturer =3D manufacturer; - } - - @NotNull - public String getManufacturer() { - return manufacturer; - } - - public void setManufacturer(String manufacturer) { - this.manufacturer =3D manufacturer; - } - -} - -//class RentalCar -package com.mycompany; - import javax.validation.constraints.NotNull; = public class RentalCar extends Car { @@ -193,16 +232,17 @@ public void setRentalStation(String rentalStation) { this.rentalStation =3D rentalStation; } - } + = - Our well-known class Car is now extende= d by - RentalCar with an additional property, - rentalStation. If an instance of - RentalCar is validated now, not only the - @NotNull constraint at the - rentalStation property would be validated, but = also - the constraint at manufacturer from the parent + Our well-known class Car from the getting started section is = now + extended by RentalCar with the additional + property rentalStation. If an instance of + RentalCar is validated, not only the + @NotNull constraint on + rentalStation would be validated, but also the + constraint at manufacturer from the parent class. = The same would hold true, if Car was an @@ -218,7 +258,7 @@
=
- Validating object graphs + Object graphs = The Bean Validation API does not only allow to validate single objects but also complete object graphs. To do so just annotate a fi= eld @@ -228,7 +268,10 @@ @Valid will be validated as well (as will be their children etc.). The following shows a simple example: = - //class Person + + Class Person + + package com.mycompany; = import javax.validation.constraints.NotNull; @@ -250,12 +293,14 @@ public void setName(String name) { this.name =3D name; } - = -} +} + = -//class car -package com.mycompany; + + Adding a driver to the car = + package com.mycompany; + import javax.validation.Valid; import javax.validation.constraints.NotNull; = @@ -266,13 +311,12 @@ private Person driver; = public Car(Person driver) { - this.driver =3D driver; } = //getters and setters ... - } + = If an instance of Car is validated, the referenced Person object will be validated as @@ -291,14 +335,13 @@ = - of type java.lang.Iterable (and - therfore its direct or indirect derivations - Collection, List a= nd - Set) + implement java.lang.Iterable + (especially Collection, + List and Set) = - of type java.util.Map + implement java.util.Map = @@ -306,8 +349,11 @@ cause each contained element to be validated, when the parent object= is validated. = - package com.mycompany; + + Car with a list of passengers = + package com.mycompany; + import java.util.ArrayList; import java.util.List; = @@ -322,40 +368,78 @@ = @NotNull @Valid - private List&lt;Person&gt; passengers =3D new ArrayList&lt= ;Person&gt;(); + private List<Person> passengers =3D new ArrayList<Person>(= ); = - public Car(List&lt;Person&gt; passengers) { - + public Car(List<Person> passengers) { this.passengers =3D passengers; } = //getters and setters ... - } + = If a Car instance is validated now, a - ConstraintValidation will be raised, if any of + ConstraintValidation will be created, if any = of the Person objects contained in the - passengers list has a null - name. + passengers list has a null name. + null values are getting ignored when + validating object graphs. +
=
- Validating your model + Validating constraints = The Validator interface is the main entry - point to the Bean Validation API. In the following we first will show = how - to obtain Validator instances using the - bootstrapping mechanism that the API provides. Afterwards you'll learn= how - to use the different methods of the Validator - interfaces followed by an overview of the information that - ConstraintViolation instances offer. + point to Bean Validation. In the following we first will show how to + obtain an Validator instance using the different + bootstrapping mechanisms. Afterwards we will learn how to use the + different methods of the Validator + interface. =
- Obtaining Validator instances + Obtaining a Validator instance = - TODO: DefaultFactory, customization, note on thread safety + The first step towards validating a class instance is to get h= old + of a Validator instance. The road to this + instance leads via the Validation class and a + ValidatorFactory. The by far easiest way is to + use the static + Validation.buildDefaultValidatorFactory() + method:ValidatorFactory factory =3D Validation.build= DefaultValidatorFactory(); +Validator validator =3D factory.getValidator();You can al= so use + the method Validation.byDefaultProvider() w= hich + will allow you to configure several aspects of the created Validator + instance:Configuration<?> config =3D Validatio= n.byDefaultProvider().configure(); +config.messageInterpolator(new MyMessageInterpolator()) + .traversableResolver( new MyTraversableResolver()) + .constraintValidatorFactory(new MyConstraintValidatorFactory()); + +ValidatorFactory factory =3D config.buildValidatorFactory(); +Validator validator =3D factory.getValidator(); +We will learn more about + MessageInterpolator and + TraversableResolver in later chapters. + + Last but not least you can ask for a Configuration object of a + specific Bean Validation provider. This is useful if you have more t= han + one Bean Validation provider in your classpath. In this situation you + can make an explicit choice about which implementation to use. In the + case of Hibernate Validator the Validator creation looks + like:ValidatorConfiguration configuration =3D Valida= tion.byProvider( HibernateValidator.class ) +config.messageInterpolator(new MyMessageInterpolator()) + .traversableResolver( new MyTraversableResolver()) + .constraintValidatorFactory(new MyConstraintValidatorFactory()); + +ValidatorFactory factory =3D config.buildValidatorFactory(); +Validator validator =3D factory.getValidator(); + + + The generated Validator instance is + thread safe and can be cached. + Now that we have a Validator instanc= e, + let's see how we can use it to validate class instances.
=
@@ -449,8 +533,10 @@
=
- Validation groups + Using groups = + +
Group sequences = @@ -458,7 +544,223 @@
= -
- +
+ Built-in constraints + + Hibernate Validator comes with some built-in constraints, which + covers most basic data checks. As we'll see later, you're not limited = to + them, you can literally in a minute write your own constraints. + + + Built-in constraints + + + + + + + Annotation + + Apply on + + Runtime checking + + Hibernate Metadata impact + + + + + + @Length(min=3D, max=3D) + + property (String) + + check if the string length match the range + + Column length will be set to max + + + + @Max(value=3D) + + property (numeric or string representation of a + numeric) + + check if the value is less than or equals to max + + Add a check constraint on the column + + + + @Min(value=3D) + + property (numeric or string representation of a + numeric) + + check if the value is more than or equals to min + + Add a check constraint on the column + + + + @NotNull + + property + + check if the value is not null + + Column(s) are not null + + + + @NotEmpty + + property + + check if the string is not null nor empty. Check if the + connection is not null nor empty + + Column(s) are not null (for String) + + + + @Past + + property (date or calendar) + + check if the date is in the past + + Add a check constraint on the column + + + + @Future + + property (date or calendar) + + check if the date is in the future + + none + + + + @Pattern(regex=3D"regexp", flag=3D) or @Patterns( + {@Pattern(...)} ) + + property (string) + + check if the property match the regular expression give= n a + match flag (see java.util.regex.Pattern + ) + + none + + + + @Range(min=3D, max=3D) + + property (numeric or string representation of a + numeric) + + check if the value is between min and max + (included) + + Add a check constraint on the column + + + + @Size(min=3D, max=3D) + + property (array, collection, map) + + check if the element size is between min and max + (included) + + none + + + + @AssertFalse + + property + + check that the method evaluates to false (useful for + constraints expressed in code rather than annotations) + + none + + + + @AssertTrue + + property + + check that the method evaluates to true (useful for + constraints expressed in code rather than annotations) + + none + + + + @Valid + + property (object) + + perform validation recursively on the associated object= . If + the object is a Collection or an array, the elements are valid= ated + recursively. If the object is a Map, the value elements are + validated recursively. + + none + + + + @Email + + property (String) + + check whether the string is conform to the email address + specification + + none + + + + @CreditCardNumber + + property (String) + + check whether the string is a well formated credit card + number (derivative of the Luhn algorithm) + + none + + + + @Digits + + property (numeric or string representation of a + numeric) + + check whether the property is a number having up to + integerDigits integer digits and + fractionalDigits fractonal digits + + define column precision and scale + + + + @EAN + + property (string) + + check whether the string is a properly formated EAN or + UPC-A code + + none + + + +
--===============2445757126768062887==--