RichFaces with Hibernate Validator

With release of Java EE 6, you can now use Bean Validation with JSF 2. If you are using JSF 1.2 (and that’s probably still most of you), you can use Seam to take advantage of Hibernate Validator. If you are not using Seam but would still like to use Hibernate Validator, RichFaces provides such functionality.

There are three tags in RichFaces which let you work with Hibernate Validator annotations:

  1. rich:beanValidator
  2. rich:ajaxValidator
  3. rich:graphValidator


Let’s take this bean as an example. I’m only using three simple annotations, but you can use everything Hibernate Validator offers.

public class Bean {
   @Length(min=3, max=15,
       message="Invalid text length; must be between {min} and {max}")
   private String text;

   @Range(min=0, max=25)
   private Integer items;

   @Email
   private String email;
}

rich:beanValidator
Using the bean above, we add rich:beanValidator to each input component to validate against constraints in the model defined by Hibernate Validator annotations:


   
   
  	
  	
  		
  	
  	

  	
  	
  		
  	
  	

  	
  	
  		
  	
        
   
   

When running it should look like this:
screenshot_094

To add Ajax validation such as invoke validation when onblur event occurs, we can add a4j:support tag to each field (just one shown here):


   
   


That’s looks like too much work, first we need to add a4j:beanValidator and then a4j:support to each component. There a simpler way to do the same.

rich:ajaxValidator
rich:ajaxValidator is a combination of rich:beanValidator and a4j:support. Taking above example adding Ajax validation to each component we use rich:ajaxValidator and specify the event via event attribute:


   
   
  	
  	
  		
  	
  	

  	
  	
  		
  	
  	

  	
  	
  		
  	
        
   
   

When onblur event occurs, Ajax request will be fired and component value will be validated. rich:ajaxValidator tag has a number of features turned on by default:

  • It is ajaxSingle=”true”. This means that only this component will be processed (executed) on the server
  • It is bypassUpdates=”true”. This means that even if the component value is valid, after Process Validation phase it will go to Render Response. This makes sense as we don’t really need to Update Model when only validating
  • We don’t have to rerender the messages tag because we are using rich:message and rich:messages. These tags are smart enough to figure out which component was validated and which error message to update and which to keep unchanged. If you want to learn why h:message need to be rerendered, read RichFaces region – partial JSF tree processing post

You can also use rich:ajaxValidator with standard JSF validators (this assuming you don’t have Hibernate Validator annotations in the bean):


   
   

If you have used Seam’s s:validate tag, then you might have seen this note in Seam’s documentation for JSF validation:

Note: specifying @NotNull on the model does not eliminate the requirement for required=”true” to appear on the control! This is due to a limitation of the JSF validation architecture.

This has to do with JSF not processing the component if no value was submitted

RichFaces takes this into account so you don’t have to set required=”true”. To check for empty value, use @NotEmpty annotation. Using @NotNull won’t work because the value passed is not null, but an empty string.

@NotEmpty
private String text;

rich:graphValidator
If you have a large form, adding rich:ajaxValidator to each one might be tedious. Instead, wrap any number of components inside rich:graphValidator and rich:beanValidator will be automatically added to each input component (similar to s:validateAll in Seam). For example:


   
   
     
  	
  	
  	
  	
  	
  	
  	
  	
        
     
   
   

rich:graphValidator will only add rich:beanValidator tag, this means that a button/link need to be clicked to submit the form. In order to have Ajax validator, rich:ajaxValidator (or a4j:support) would still need to be added to each component. For example:


   
   
     
  	
  	
            
        
  	
     
   
   

rich:graphValidator comes with one more useful feature. It can validate the bean once all the values have been set. This is handy if you need to sum to properties and make sure the sum is of certain value. Let’s say we have this bean:

public class TotalBean  {
   @Range(min=3, max=25, message="Items must be between {min} and {max}")
   private Integer items=1;

   @Range(min=3, max=100, message="Parts must be between {min} and {max}")
   private Integer parts=1;

   @Min(value=10, message="Items and parts total must be greater than {value}")
   public Integer getTotal (){
	return (this.items + this.parts);
   }
}

and then this JSF page:



   
      
         
	    
	    

	    
	    
	
	
   

When Submit is clicked, the form will be validated in the standard way. Notice that rich:graphValidator has value attribute bound to the bean itself #{totalBean}. This tells RichFaces to validate the whole bean again after Update Model phase. The individual properties will be validated but already hold valid values (as we passed Process Validations phase). During this step, we also going to validate getTotal(). It wasn’t validated when form was submitted as it wasn’t bound to any page components. When getTotal() is validated, we are going to make sure that the sum of parts and items is at least 10.

screenshot_095
In the image above, individual fields passed validation, but when the whole bean was validated, getTotal() failed because the sum of items and parts is less then 10.

21 thoughts on “RichFaces with Hibernate Validator

  1. Can you tell me the versions of jars you use for this example? Specifically, RichFaces and Hibernate-Validator.
    I was only able to make this work with an odd version coupling:
    Hiberate-Validator: 3.1.0.GA; RichFaces 3.3.3.Final

    I had tried Hibernate-Validator 4.0.2.GA (with validation-api-1.0.0.GA), and RichFaces 3.3.2.SR1, mixing and matching the 2 Hibernate-Validator versions with the 2 RichFaces versions, none of the other combo worked.

    The key importance is that RichFaces 3.3.3 is JSF 2, and RichFaces 3.3.2.SR1 is JSF 1.2. Since we still use JSF 1.2, I would like NOT to use RichFaces 3.3.3.

    If you still have a working version that you can share, that will be great!

    Thanks much.
    Shan

  2. The first thing which you tried (Hibernate 3.1, RichFaces 3.3.3) is actually fine. RichFaces 3.3.3 works with JSF 1.2 as well. In fact, RichFaces 3.3.3 is the latest and most stable version for JSF 1.2. I do have a sample project that I can send you if you are interested.

  3. I would like to use HibernateValidator and RF 3.3.3, but I have a problem with @notnull. BranValidator doesn’t check this constraint. If I use @notempty it’s working ok. What’s the problem?

  4. When using JSF 1.2, if you don’t submit any value, the component is not processed at all and thus validation is not invoked. You need to set required=”true” or use tags from RichFaces. Tags in RichFaces take care of this problem.

  5. Max,

    Thank you for your excellent post ! It has been very useful to me.

    I started to use “graphValidator” to validate the whole bean, but I have some trouble to show the messages where I need them.

    I’m showing messages for each input field with facelets (seam-gen style, next to the field), and I have a “rich:message” on top of the page with globalOnly=”true.”

    “Global messages” (like “Items and parts total must be greater than {value}” in your example) are enqueued but not displayed, unless I change rich:message’s property to globalOnly=false, which is not the idea. I can’t realise which component the message is attached to.

    Thanks in advance for yor help.
    Rodo

  6. Max,

    I’ve just found one way to to this.
    I’ve referenced graphValidator Id from richMessages components. It seems to work fine.

    Thanks again.
    Rodo

  7. Hi Max,

    Excellent post! .. I had been trying to validate a non-entity seam component using various hack. For past 3 days i have been having dreams(nightmares) about possible solutions 😛

    Your post helped me solve the problem. Can you please help me with the following issue

    1. I want to use messages.properties to display localized messages on the screen using the annotation as –

    @Pattern(regex=QGlobalConstants.PWD_PATTERN_STR,message=”#{messages[‘pwd.pattern.error’]}”)
    String oldPassword;

    However, on screen, I am unable to see the message. My properties file has the key-value pair.

    pwd.pattern.error=Please enter password in specified format.

    Moreover, this validation work fine if i don’t use inside input components.

    Why the messages.properties file is not being picked during validation?

    Thanks,
    Shriharsh

  8. hi Max,

    Validation is getting fired. Message is displayed (which is ‘#{messages[‘pwd.pattern.error’]}’ ).

    I am trying to use ResourceBundle to internationalize my app. With Seam Internationalization support I am able to put localized text in my messages across the application.

    But on the hibernate validator annotations on POJO property, it isn’t working. However, the same thing works if I use hibernate annotation on an Enitity Bean.

    Thanks,
    Shriharsh

  9. I use JSF1.2 on JBoss 5.1GA. I’ve tried these validators both on h:inputText(doesn’t work) and rich:inplaceInput(works) and a JSF convertor jumps in the second time i lose focus on the component, instead of the annotation message i give (that works the first time), no matter what rich faces validator i use (except rich:graphValidator which doesn’t seem to work for me agai):

    @Pattern(regex = “(\d{1,9}\.\d{1,3})|(\d{1,9})”, message = “mymessage”)
    private BigDecimal soldQuantity;

  10. Hello, Thanks for this article. As such I am able to make this code run at my end. But please tell us about the jars required for this kind of application. Second, in mu case, I am not able to run the email validation. please suggest. what could be the possible reason.

    Thanks,
    Jaikrat Singh

  11. Hey Max,
    Thanks for your quick reply. The email started working, I was not using the notation. Instead, I was using some regex pattern annotation check in the bean. That should also work but I can ignore that for time being.

    Thanks for this article again, pls keep posting.

    Thanks
    Jaikrat Singh

  12. Hello Max, I tried to follow the list of the jars given by you but with that my email validation gets failed when I move the cursor to next input field keeping email input field empty.

    error:-

    root cause

    java.lang.ClassNotFoundException: org.apache.log4j.Level
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
    org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:189)
    org.slf4j.LoggerFactory.bind(LoggerFactory.java:112)
    org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:105)
    org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:235)
    org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:208)
    org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:221)
    org.hibernate.annotations.common.Version.(Version.java:11)
    org.hibernate.annotations.common.reflection.java.JavaReflectionManager.(JavaReflectionManager.java:35)
    org.hibernate.validator.ClassValidator.(ClassValidator.java:122)
    org.hibernate.validator.ClassValidator.(ClassValidator.java:104)
    org.richfaces.validator.HibernateValidator.createValidator(HibernateValidator.java:157)
    org.richfaces.validator.HibernateValidator.getValidator(HibernateValidator.java:141)
    org.richfaces.validator.HibernateValidator.validateClass(HibernateValidator.java:120)
    org.richfaces.validator.HibernateValidator.validateBean(HibernateValidator.java:205)
    org.richfaces.validator.HibernateValidator.validate(HibernateValidator.java:179)
    org.richfaces.validator.ObjectValidator$ValidationResolver.setValue(ObjectValidator.java:458)
    org.apache.el.parser.AstValue.setValue(AstValue.java:204)
    .
    .
    .
    etc

    But when I add log4j-boot.jar this jar in my lib it works fine. Any idea what is happening here.

    Thanks
    Jaikrat Singh

  13. Hi max,
    I want to know if we can use rich:graphValidator for a dataTable which contains a check box and need to check if at least one check box is ticked else show a validagtion message. can you please help me in this.

    • I don’t believe so, but you should repost this question on RichFaces forum. It’s been a couple of years since I used RichFaces.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s