I've been blogging elsewhere about validation in Seam recently and been getting some good feedback regarding what has been found out by myself and others, so I thought I'd kick off my blogging here with a quick summary of what has been discovered.
Let's imagine for a moment we have a simple form with a simple backing bean.
The form:
<h:form> <s:validateAll> <f:facet name="beforeInvalidField"> <s:div styleClass="errors"> <s:message //> <//s:div> <//f:facet> <table> <tr> <td>Product name:</td/> <td> <s:decorate id="nameDecorate"> <h:inputText id=Namevalue="#{product.name}"/> <//s:decorate> <//td> <//tr> <//table> <h:commandButton type="submit" value="Save Product" action="#{productService.saveProduct}" /> <//s:validateAll> <//h:form>
The backing bean:
@NotNull @Length(min=3, max=20) private String name; // getters and setters ...
OK, when we submit this form without filling in the name, we will see a large stack trace and are redirected to the debug page (assuming you've got that configured). This is caused by no validation from the front end being performed so the value of 'name' is not being checked before being passed on to be persisted. At this point Hibernate then checks against its validation rules that DO take into account our @NotNull annotation and complains bitterly about 'name' being null.
Why is this happening? Well, the simple answer is that if you want your annotations to be used for front-end validation, you must add a required attribute to the form element and set it to true (ie: required="true"). This acts as a 'hint' to Seam to run the validation from the backing bean at the front end.
Now, let's consider that we have a @Pattern to validate on a null-able field. To check this you would still need to have the required attribute set to true. Even though the field is not, technically, required. This would then allow you to validate against the @Pattern as you would expect.