Help

Good news!

Bean Validation is now in proposed final draft and available for download on the JCP website. Bean Validation standardizes the way constraint validations are defined, declared and validated in objects graphs. By using annotations such as @NotNull, @Email etc, you express constraints on your domain model once (following the DRY principle) and let them be validated automatically by different layers of you application. Bean Validation also exposes constraints via a metadata query API which is useful for frameworks interacting beyond Java like javascripts libraries or database schema generators.

Here are the main highlights of this proposed final draft:

  • Type-safe constraint validator
  • XML configuration and XML mapping support
  • Clearer names
  • integration into JPA 2 and JSF 2
  • More built-in constraints

Type-safe constraint validatorS

Constraints are now validating particular types (like String and Collection) in a type-safe way. You can even have several ConstraintValidator implementations associated to a given constraint. Each ConstraintValidator is dedicated to a specific type.

@Constraint(validatedBy = {
	SizeValidatorForString.class,
        SizeValidatorForCollection.class } ) 
public @interface Size { 
    String message() default "{constraint.size}"; 
    Class<?>[] groups() default {}; 
    int min() default 0;
    int max() default Integer.MAX_VALUE;
}

public class SizeValidatorForString implements<Size, String> {
	public void initialize(Size size) {}
	public boolean isValid(String value, ConstraintValidatorContext context) {}
}


public class SizeValidatorForCollection implements<Size, Collection> {
	public void initialize(Size size) {}
	public boolean isValid(Collection value, ConstraintValidatorContext context) {}
}

The appropriate ConstraintValidator is chosen automatically by the Bean Validation provider. Even better, an IDE or an annotation processor (see another usage here) can warn you if you place a constraint on a property of an incompatible type.

@Size //invalid usage of @Size
Number number;

XML configuration and mappings

Support for XML configuration via META-INF/validation.xml and XML mapping (ie using XML instead of annotations) have been added. Check it out if you are interested and give us feedback. The configuration can also be done entirely programmatically if needed, XML is completely optional.

Clearer names

We took a second look at all the class names and cleaned that up, especially in the bootstrapping API. Names are much more consistent and clear.

Integration with JPA 2 and JSF 2

It's official now, Bean Validation is integrated with JPA 2 and JSF 2. Even better, it requires zero configuration in your application. Pretty neat. Check JSF and JPA's specifications to read more about it.

More built-in constraints

We have added a few new built-in constraints. @Pattern which validates a String against a regular expression. @DecimalMin and @DecimalMax which uses BigDecimal style notation and range to define boundaries. @Min and @Max are still be used for integer boundaries.

@Pattern(regexp="[0-9]*")
String number;

@Max(500000)
BigDecimal salary;

@DecimalMax("27.5")
BigDecimal luggageWeight;

Feedback

Additional minor and not so minor enhancements and bug fixes have been done. See our JIRA changelog for more details.

We listened to your feedbacks since the public draft and are pretty pleased with the current status of the spec. Do more, go read the proposed final draft and give us even more feedbacks (spec, forums).

You can already use Bean Validation by downloading Hibernate Validator 4, we are almost feature complete now!

Many thanks to all the contributions we received inside and outside the JCP. This spec is very solid and will remove one of the remaining painpoints of Java SE and Java EE developments.

14 comments:
 
01. Apr 2009, 19:10 CET | Link
Sakuraba | saku(AT)raba.jp

This sure looks very nice. I especially like the type safe constraint validators. Types are Java's natural features and we should let the compiler help us as much as it can.

Can you provide a snippet of how one would actually validate such a class? How does one get a hold of the actual validation errors and use them to display specific, i18nize error messages on some element of a html form for example?

ReplyQuote
 
01. Apr 2009, 21:21 CET | Link
anonymous
public class SizeValidatorForString implements<Size, Collection> {
        public void initialize(Size size) {}
        public boolean isValid(Collection value, ConstraintValidatorContext context) {}
}

should be SizeValidatorForCollection.

 
02. Apr 2009, 16:26 CET | Link
Georges Berscheid

Cool! This is really good news, congratulations. While browsing through the spec, I couldn't find an answer to the following question:

class MyEntity {
  private int a;
  private int b;
}

Is there any easy way to define the constraint a>b ?

 
02. Apr 2009, 16:58 CET | Link
dlemoing

This can be done using a class level constraint for instance :

@MyEntityConstraint(...)
class MyEntity {
...
}
@Documented
@Constraint(validatedBy = MyEntityConstraintValidator.class)
@Target({ TYPE })
@Retention(RUNTIME)
public @interface MyEntityConstraint {
    ...
    String message() default "{constraint.myentity}";
    Class<?>[] groups() default { };
}
public class MyEntityConstraintValidator implements ConstraintValidator<MyEntityConstraint, MyEntity> {

    public void initialize(MyEntityConstraint constraint) {
    }

    public boolean isValid(MyEntity value, ConstraintValidatorContext constraintValidatorContext) {
        if ( value == null ) {
            return true;
        }
        return checkASuperiorThanB(value);
    }

    private boolean checkASuperiorThanB(MyEntity value) {
        return value.getA() > value.getB();
    }
}
 
02. Apr 2009, 17:06 CET | Link
dlemoing

Another solution, add a method in your class that tests the coherence of the objet and add an AssertTrue constraint on it :

class MyEntity {
    private int a;
    private int b;
    ...
    @AsserTrue(...)
    public boolean isASuperiorThanB() {
        return a > b;
    }
}
 
02. Apr 2009, 18:44 CET | Link
man4j

1. How integrate this validator to JSF 2.0? I read the specification and search in google, but not find good answer. 2. When i use this validator with hibernate? And when hibernate do support JPA 2.0? Thanks.

 
02. Apr 2009, 23:48 CET | Link

Hi Saku, Explicitly validating looks like that:

// cache the VF somewhere
ValidatorFactory vf = Validation.buildDefaultValitatorFactory();
 
Validator v = vf.getValidator();
Set<ConstraintViolation> errors = v.validate(address);
for(ConstraintViolation error : errors) {
    String userErrorMessage = error.getMessage();
    Object invalidValue = error.getInvalidValue();
    ConstraintDescriptor constraint = error.getConstraintDescriptor();
    //...
}

In practice, Java EE will inject Validator or ValidatorFactory for you

@Stateless
public class Action {
    @Resource Validator v;

    public void doThings(Address address) {
        Set<ConstraintViolation> errors = v.validate(address);
        ...
    }
}

or even better JSF or JPA will apply validation for you

 
02. Apr 2009, 23:48 CET | Link

Fixed thanks.

 
02. Apr 2009, 23:53 CET | Link

1. It will work automatically as soon as Bean Validation is in the classpath. Check out the JSF 2 proposed final draft for some details. 2. We need to work on that and that will be part of Hibernate JPA 2 implementation. I think you will see prototypes quite soon but there is no date yet. Note that the current stable version of Hibernate Core works with the current version of Hibernate Validator already and you have all the goodies, it's not spec compliant but it sure looks like it.

 
17. Apr 2009, 02:50 CET | Link
karthik

Why is Proposal for method-level validation not part of the core? It would be nice to have in the core proposal as frameworks like Spring MVC pretty much accept parameters in the controller methods.

Also, The built in constraint annotations cannot be specified on the method parameter. Does it make sense to add this @Target(value {ElementType.PARAMETER}) to the constraint definitions?

- Karthik

 
21. Apr 2009, 22:01 CET | Link
Emmanuel Bernard wrote on Apr 02, 2009 17:48:
In practice, Java EE will inject Validator or ValidatorFactory for you ... or even better JSF or JPA will apply validation for you
I certainly hope that JSR 303 / JPA integration means that validation is not be automatically triggered on entityManager.persist, it should only (IMHO) be triggered on transaction commit. And therefore I hope EJB-419 gets fixed before JSR 303 is finally integrated with Hibernate, without transactional validation for nulls, JSR 303 will not be as comfortable and usable as it could be.

I also wonder if it will finally be possible to call validation on all the dirty objects in the entityManger at will (that is call validation to all the objects that are dirty for a particular transaction, but not on entityManager.persist or transaction commit, but whenever we want to know if anything is invalid).

I finally I wonder... will it be possible to validate for different constraints when deleting, updating or inserting? or will we limited to insert & update only...
 
28. May 2009, 19:01 CET | Link

Hi does bean validator support JPA entities validation through their attributes in XML (maxlength, not null, etc)? or only through annotations? thx

donny

 
03. Dec 2009, 01:13 CET | Link
Rodrigo Bento | rodrigo.bento(AT)gmail.com

Hello Emmanuel, I appreciate your work very much. Keep up with the great work.

My doubt is, with this new specification and JSF 2, will that issue regarding the need of 'required true' attribute to trigger HibernateValidator validations be fixed?

 
02. Jun 2010, 02:20 CET | Link
MSREDDY

Is there any way to reload ResourceBundle at runtime without stopping the server with Hibernate Validator 4.1.0.Beta1?

Post Comment