Tuesday, December 27, 2011

Using Bean Validation together with ExtVal in JPA and JSF

With the release of WebLogic 12c we can finally try out the native support for Bean Validation ( JSR-303) in JPA & JSF. With JSR-303 we can use this validation framework on the back-end side ( EJB Session Bean ) and on the managed bean of the JSF Web applications, so one framework which can do it all. It will save us a lot of time in making business rules and no need for validators on our JSF UI Components.
To make this even better I will combine this with Apache MyFaces Extensions Validator. This framework can be used with JSF ( there is a generic library and a special one for Trinidad ) and its supports the Bean Validation. ExtVal also has some extra features.



  • Type-safe group validation
  • Model validation
  • Severity aware validation
  • Client-side validation
  • Sorted violation messages
  • Dependency injection support for constraint validators
  • Mapped constraint source (e.g. for using DTO's with BV)
  • Support of @Valid


In this blog I won't give you all the possible validations options you can have in the Bean Validation or in ExtVal framework but I will try to give you a jumpstart, how to setup this up and get everything working.

Before I start I got this working with WebLogic 12c and use OEPE 12c as my IDE. For the JSF part I use Apache MyFaces Trinidad 2.0.0 which support JSF 2.0.

Let's start with the JPA part.

Here I have created a department entity which is based on the department table of the HR demo schema in the Oracle database.

On the departmentName attribute I added some validation annotations like NotNull , Size and Pattern.


On the Pattern annotation I added a custom resource bundle message ( use {} ), I only do it for pattern annotation because Size or NotNull will have it's own default message in JSF.

Bean validation is the default now so we would see the Eclipselink error anymore. So when we try to persist an entity which violates these annotations we get an error like this.

With a javax.validation.ConstraintViolationException on a prePersist callback event. This error won't give you a lot of information about the error.

You got the option to disable the Bean Validation in Eclipselink by setting the validation-mode to NONE. This way you will get the constraint error.


Like this.

So how we can retrieve these validations errors. For example I can do this on the client side before I invoke the EJB Session bean or do it inside the Session Facade methods.

We need to use the resource annotation to retrieve the Validator.
(@Resource Validator validator; )
In the department persist we can pass on the department entity to the validatior.
Set<ConstraintViolation<Department>> violations = validator.validate(department);
And loop through the violations with this as result.

error size: 2
invalid value for: 'departmentName': Name must between 2 and 30 characters
invalid value for: 'departmentName': {departmentNameValidation}



Now we can go the JSF part.
Here I do the same but then from a managed bean which is called from a commandButton.



I changed the violations to Faces Messages and skip the persist part.


This is all standard Bean Validation stuff so let's check out the ExtVal part.

I added the following libraries to the lib folder of the WEB-INF

The jsr303-tck and the validation-api jars are from Hibernate Validator and the rest is from MyFaces ExtVal. Where I remove the myfaces-extval-generic-support-2.0.5.jar because I could use the trinidad one.

To test the validation I made a simple JSF Trinidad page where you can see there are no validator or convertors defined.



In the Trinidad table I show all the departments and change for example the department Name to 1 char which violates the Size annotation.

When I use invalid characters for the department Name then I get the resource bundle message.

To make this resourcebundle work I need to set a context parameter in the web.xml which points to our own resourcebundle.

<context-param>
    <param-name>org.apache.myfaces.extensions.validator.CUSTOM_MESSAGE_BUNDLE</param-name>
    <param-value>resources.application</param-value>
</context-param>

The last part is to show you the ExtVal part. I used this managed bean which are used in the JSF page.


departmentName use the Bean Validation framework and departmentLocation use the ExtVal framework.
With this as result.


When you want to know more about ExtVal or Bean Validation you definitely should read this example chapter of Bart Kummel's Book about MyFaces Development.

Here is the example project on github. https://github.com/biemond/OEPE_examples/tree/master/beanValidation


5 comments:

  1. greate post! do I have to use hibernate inoreder to use it?
    where can I download this example from??

    ReplyDelete
  2. great post! do I have to use hibernate with this example? where can i download this example from?? thank's!

    ReplyDelete
  3. Hi,

    the hibernate is the reference implementation for the bean validation.

    I think apache extval can work without.

    thanks

    ReplyDelete