This is my attempt to make the Hibernate Validator play nicely with WebWork (and presumably Struts 2 although that hasn't been tested). The validator is basically a copy of the VisitorFieldValidator that ships with WebWork.

Get The Code

It's all of one file, so I haven't bothered making a JAR. Just drop in the appropriate package in your source tree.

Other Things You'll Need

  • Hibernate Core and Annotation JARs (http://www.hibernate.org/6.html)
  • validators.xml in your classpath referencing this validator. I've got a sample that I use, but you may want to pull the latest validators.xml file from your WebWork distribution and just add the custom validator line to it.

How to Use

  1. Annotate your domain classes using the Hibernate's built in validators or your own custom validators.
  2. Create the WebWork validation xml file for your action and add something like this to it to have your domain object validated (in this example the property being validated is "issue"):
        <field name="issue">
          <field-validator type="hibernate">
              <param name="appendPrefix">true</param>
              <message></message>
          </field-validator>
        </field>

Issues

Well, they aren't issues with this code directly, but challenges that come up now that you're using your domain model directly for validation:

  • How best to validate data type of input. Date validation, numeric validation, etc. now falls solely on the WebWork type conversion process. This works but the messages that are returned to the user aren't the best.
  • How to validate foreign key relationships. An example would work best here I think:

Let's say we have a class called Issue that has an "assignedTo" property of type Person. They look something like:

public class Issue {
(other properties omitted)
  @ManyToOne
  @JoinColumn(name = "assignedToPersonId")
  private Person assignedTo;

(getters/setters omitted)  
}

public class Person {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  @Required(message="You must enter a value for first name.")
  private String firstName;

  @Required(message="You must enter a value for last name.")
  private String lastName;

(getters/setters omitted)  
}

I typically just have a drop down list in my UI called "issue.assignedTo.id" that populates the id of the assignedTo property. That is enough to get the Issue saved.

So, now the problem... How do we annotate the assignedTo property to specify that it is required? @NotNull/@Required doesn't work because WebWork instantiates an instance of Person for you automatically even if the end user didn't select an assigned to person. The other logical thing to try would be @Valid as this makes sure the Person is valid. Unfortunately this won't work in this case because we haven't populated the first/last name which are required fields on Person.

So, needless to say, I'm still struggling with this one. I'm open to ideas if anyone has any.