DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Spring 4 + Hibernate 4 + MySQL 8 + Maven Integration Using Annotations Configuration [Video]
  • Dependency Injection in Spring
  • How Spring and Hibernate Simplify Web and Database Management
  • SmartXML: An Alternative to XPath for Complex XML Files

Trending

  • Building Scalable and Resilient Data Pipelines With Apache Airflow
  • Rethinking Recruitment: A Journey Through Hiring Practices
  • Segmentation Violation and How Rust Helps Overcome It
  • Chaos Engineering for Microservices
  1. DZone
  2. Coding
  3. Languages
  4. Using Hibernate Validator to Cover Your Validation Needs

Using Hibernate Validator to Cover Your Validation Needs

By 
Avi Yehuda user avatar
Avi Yehuda
·
Apr. 15, 10 · Interview
Likes (0)
Comment
Save
Tweet
Share
133.8K Views

Join the DZone community and get the full member experience.

Join For Free

Recently I had to choose a validation framework or write one by myself.  First I thought, no big deal, validation is not a complicated issue. But the more you think about it, the more you come to the conclusion that it is not as shallow as you think – you need to validate different types, you have different groups and many more issues… In short, writing a validation framework by yourself demands a lot of work.

Luckily, JSR 303 solves this and the Hibernate implementation of the JSR does a pretty good job.

  • Hibernate Validator is a JSR 303 implementation for bean validation.
  • The way to work with this framework is first, to define constraints for java bean fields, and then, validating the bean.

JSR 303

  • JSR 303 – defines a metadata model and API for entity validation.
  • The default metadata source is annotations, with the ability to override and extend the meta-data through the use of XML.
  • The API is not tied to a specific application tier or programming model.
  • It is specifically not tied to either the web tier or the persistence tier, and is available for both server-side application programming, as well as for rich client Swing application developers.

Hibernate Validator features

  • Defining validation data using annotation and/or XML.
  • Full object validation (including inner objects using recursion)
  • Create customized constraints and validators.
  • Customized error messages.
  • Define groups(profiles).
  • Create a Traversable Resolver.

Using constraints

 Using XML

  • Here is a simple example of a constraint using xml:
<constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                     xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"                     xmlns="http://jboss.org/xml/ns/javax/validation/mapping">    <default-package>com.mytest</default-package>    <bean class="MyBean"  >        <field name="x"  >            <constraint annotation="javax.validation.constraints.NotNull"/>        </field>        <field name="y"  >            <constraint annotation="javax.validation.constraints.Min">                  <element name="value">2</element>            </constraint>        </field>      </bean></constraint-mappings>
  • In this example the field x can not be null.
  • The field y can not be less than 2. Notice that the “Min” constraint has inner element – “value”.
  • Notice the tag “<default-package>”. It indicates the root path of all the beans.
  • See also directions on how to load the XML file while using the validator.


Using annotations

  • Here is a simple code example:
public class MyBean{@NotNullString x;@Min(2)int y;}
  • This example is the equivalent to the previous xml example.


Using both

  • Using both annotations and XML constraints is possible.
  • By default if you are using both only the XML is taken, unless you are using the attribute ‘ignore-annotations’ in the XML.
  • Example:
<constraint-mappings     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"    xmlns="http://jboss.org/xml/ns/javax/validation/mapping">    <default-package>com.mytest.beans</default-package>    <!--  ignore-annotations default is true. After changing to 'false',                      by default, annotations will be stronger -->    <bean class="MyBean" ignore-annotations="false"    >          <field name="x1"  > <!-- ignore-annotations default is false,                                                      annotation is stronger -->            <constraint annotation="javax.validation.constraints.Min">                 <element name="value">2</element>            </constraint>        </field>         <field name="x2"  ignore-annotations="true"    >  <!-- XML is stronger -->            <constraint annotation="javax.validation.constraints.Min">                 <element name="value">2</element>            </constraint>        </field>    </bean> 
  • Notice that the attribute ignore-annotations appears twice – for a bean and for a field.

    • The default for a bean is ignore-annotations=”true” – this means that if you have an XML constraint for a bean, it will cancel the attribute constraint, Unless you will indicate that by ignore-annotations=”false” (look at the example).
    • The default for a field is ignore-annotations=”false”. This means that by default annotations for a field are stronger (this is of course after you indicated that that the bean itself wont ignore annotations). If you wont that the XML will be stronger than you have to indicate that by ignore-annotations=”true” (look at the example in the “x2″ constraint).

Existing constraints

  • These constraints are a part of the hibernate validation framework:
  • Constraint path Parameters
    javax.validation.constraints.AssertTrue(none)
    javax.validation.constraints.AssertFalse(none)
    javax.validation.constraints.NotNull(none)
    javax.validation.constraints.Null(none)
    javax.validation.constraints.Maxvalue(mandatory)
    javax.validation.constraints.Minvalue(mandatory)
    javax.validation.constraints.DecimalMaxvalue(mandatory)
    javax.validation.constraints.DecimalMinvalue(mandatory)
    javax.validation.constraints.Patternregexp(mandatory)
    flags(optional)
    javax.validation.constraints.Past(none)
    javax.validation.constraints.Future(none)
    javax.validation.constraints.Sizemin(optional)
    max(optional)
    javax.validation.constraints.Digitsinteger(mandatory)
    fraction(mandatory)
    org.hibernate.constraints.Email(none)
    org.hibernate.constraints.Lengthmin(optional)
    max(optional)
    org.hibernate.constraints.NotEmpty(none)
    org.hibernate.constraints.Rangemin(optional)
    max(optional)


 

 

 

 

 

Inner objects constraints

  • If you have nested beans (beans which contain other beans) you can easily let the system validate also the inner objects by using the constraint ‘valid’.
  • XML example:
<constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                     xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"                     xmlns="http://jboss.org/xml/ns/javax/validation/mapping">    <default-package>com.mytest.beans</default-package>    <bean class="MyBean" ignore-annotations="false"    >         <field name="innerBean">           <valid/>   <!-- validation for an inner object -->        </field>      </bean>    <bean class="InnerBean" ignore-annotations="false">        <field name="xx">            <constraint annotation="javax.validation.constraints.NotNull"/>        </field>    </bean></constraint-mappings>

 

  • Annotation example:

 

public class MyBean{@Valid  //inner bean to be validated separatelyprivate InnerBean innerBean; public InnerBean getInnerBean() {return innerBean;}public void setInnerBean(InnerBean innerBean) {this.innerBean = innerBean;}}public class InnerBean {        @NotNullString xx; public String getXx() {return xx;}public void setXx(String xx) {this.xx = xx;}}

Validating

  • Example of a simple validation:
ValidatorFactory factory =          Validation.buildDefaultValidatorFactory();Validator validator = factory.getValidator();Set<ConstraintViolation<MyBean>> constraintViolations =           validator.validate(bean);

Loading a constraints XML file

  • As mentioned, you don’t have to use an XML file for defining constraints, you can just use annotations. But if you do want an XML file, you will have to load the file.
  • Example:
Configuration<?> config =          Validation.byDefaultProvider().configure();FileInputStream in =     new FileInputStream(               new File("resources/demo-constraints.xml"));config.addMapping(in);// Building the customized factory// (along with the changed configuration)ValidatorFactory factory = config.buildValidatorFactory();Validator validator = factory.getValidator();

The result

  • The result(as you can see in the example above) is a collection of ConstraintViolation.
  • Each ConstraintViolation holds the problematic field, it’s value and the error message itself.
  • Example of reading the result:
Set<ConstraintViolation<MyBean>> constraintViolations =               validator.validate(bean);//printing the resultsfor (ConstraintViolation<MyBean> constraintViolation : constraintViolations) {System.out.println(constraintViolation.getPropertyPath() + " -> " +constraintViolation.getMessage());}
  • This object can be easily transformed to a more generic object like ValidationException or CyotaSoapException and so on.

Customized constraints and validators

  • If you want to create a new constraint you will have to create the constraint annotation interface and the validator class.

Creating the constraint interface

  • Here is a simple constraint example
@Target( { METHOD, FIELD, ANNOTATION_TYPE })@Retention(RUNTIME)@Constraint(validatedBy = MyValidator.class)@Documentedpublic @interface MyConstraint{// These next parameters exist in every constraintString message() default "{com.mytest.MyConstraint.message}";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};// These next parameters are added// They are the constraint's attributesString myOptionalValue() default ""; //this parameter has a default valueString myMustValue();  //this parameters need to get input from the user}
  • Notice the @Constraint annotation. It signifies the class that suppose to validates this constraint.
  • Notice the message class member. It holds an error message or, like in this case, an error code. It will later be interpreted as a literal error message.
  • The payload member holds payload objects. These objects carry additional data attached to the constraints that can be fetched when validating.


Nested constraints

  • You can also overload constraints very easily.
  • For example, let’s say I want to create a new constraint which also checks that the value is not null.

          In this case, all I have to do is this:

@Target( { METHOD, FIELD, ANNOTATION_TYPE })@Retention(RUNTIME)@Constraint(validatedBy = MyValidator.class)@Documented@NotNullpublic @interface MyConstraint{String message() default "{com.mytest.MyConstraint.message}";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};}
  •  In the example, notice the @NotNull annotation.


Creating the validator class

  • Here is an example of a simple validator:
public class MyValidatorimplements ConstraintValidator<MyConstraint, String> {MyConstraint MyConstraint;/** * This function recives the constraint instance * (along with the user values) */public void initialize(MyConstraint MyConstraint) {this.MyConstraint=MyConstraint;}/** * The value is the actual object instance. * */public boolean isValid(String value,                ConstraintValidatorContext arg1) {                 //using input from the userreturn value!=null &&                    value.startsWith(MyConstraint.myMustValue());}}
  • The above code shows an example of a validator which validates that the value of the given string starts with a given character.
  • The validator implements the ConstraintValidator interface.
  • Notice that the constraint is given as input to the initialize() function.
  • The value itself is input to the isValid() function


Customizing error messages

  • Each error has an error template.
  • The error template is defined in the constraint annotation interface.
  • This error template is later translated into an error message.
  • The actual error message may be defined in 2 places:


1. Inside the constraint deceleration.
The error message be defined when defining the constraint, whether it you are using XML or annotations.
XML example:

<bean class="MyBean" ignore-annotations="false"    >        <field name="x"  ignore-annotations="true"    >            <constraint annotation="javax.validation.constraints.Min">                <message>x is too small</message> <!-- message can appear inside the XML -->                 <element name="value">2</element>            </constraint>        </field>    </bean>

Java example:

public class MyBean{@Min(value = 2, message="x is too small")private String x;public String getX() {return x;}public void setX(String x) {this.x = x;}}

2. Using a separate properties message.

You may want to load a separate properties file containing the error messages according to the error template. loading the messages properties file is done using the validation factory configuration:


Configuration<?> config =          Validation.byDefaultProvider().configure();// Using a properties file for customized error messagesFileInputStream in =          new FileInputStream(new File("resources/messages.properties"));ResourceBundleMessageInterpolator messageInterpolator =new ResourceBundleMessageInterpolator(                                                  new PropertyResourceBundle(in));// Setting a messages properties fileconfig.messageInterpolator(messageInterpolator);in = new FileInputStream(new File("resources/demo-constraints.xml"));config.addMapping(in);// Building the customized factory (along with the changed configuration)ValidatorFactory factory = config.buildValidatorFactory();Validator validator = factory.getValidator();

Using groups

  • There may be occasions when you will want to create a single constraint but with different values for different situations.
  • For example, let’s say you want to create a username field and let him a minimum constraint. But, one time it will have minimum of 5 characters and another time it will have minimum of 6 characters.
  • For cases like this you will want to use groups.
  • To do so, you will have to create a group, create constraints for that group and last, validate objects by attaching the group.
  • Please follow the steps below


Create a group

  • To create a group you simply create a new interface.

example:

public interface MyBeanGroup{}


Create a constraint for the group

  • XML example:


<bean class="MyBean" ignore-annotations="false"    >        <field name="x"  >            <constraint annotation="javax.validation.constraints.NotNull">            <groups><value>com.mytest.groups.MyBeanGroup</value></groups>            </constraint>        </field> </bean>
  • Annotations example:


public class MyBean{@NotNull(groups = MyBeanGroup.class)private String x; public String getX() {return x;}public void setX(String x) {this.x = x;}}

 

Validate an object using the group

Set<ConstraintViolation<MyBean>> constraintViolations =                   validator.validate(bean, MyBeanGroup.class);

The default group

  • The default group is javax.validation.groups.Default.
  • If you don’t assign a constraint any group it applies to the default group.
  • If you are validating an object without using any group, it is validated as a part of the default group.


Groups inheritance

  • You can also create an group inheritance tree.
  • In this way, if you validate an object using a group it will prefer constraints that are defined to it. But if there are no such constraints, then it will also take the constraints of it’s parents.
  • Example, this is a group which inherits the default group:
public interface MyBeanGroupextends javax.validation.groups.Default{}
  • All the constraints that are defined for that group will apply to it.
  • But also all the constraints which do not apply to any group(and by which apply to the default group), will also apply to it, since it exteds the default group.


Jar dependency

  • validation-api-1.0.0.GA.jar
  • hibernate-validator-4.0.2.GA
  • slf4j-api-1.4.2.jar
  • slf4j-simple-1.4.2.jar
  • log4j-1.2.15.jar

Only for java5

  • jaxb-xjc-2.1.6.jar
  • jaxb-impl-2.1.6.jar
  • jaxb-api-2.1.jar
  • activation-1.1.jar
  • geronimo-stax-api_1.0_spec-1.0.1.jar


References

  • JSR 303 specification- Bean validation
  • Product main page
  • Hibernate Validator documentation

 

Download demo project

 

from http://www.aviyehuda.com/

Hibernate XML Spring Framework Annotation Object (computer science) Error message

Opinions expressed by DZone contributors are their own.

Related

  • Spring 4 + Hibernate 4 + MySQL 8 + Maven Integration Using Annotations Configuration [Video]
  • Dependency Injection in Spring
  • How Spring and Hibernate Simplify Web and Database Management
  • SmartXML: An Alternative to XPath for Complex XML Files

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: