As you may have noticed, it's almost spring cleaning time and everyone pushes its new JSR proposal following EE 7. I wanted to share with you what I had in mind for Bean Validation. This is by no mean a definite list but more a starting point to discuss things further. In the end the EG and the community will shape the spec.
First off, I think people have been very pleased with Bean Validation (no major flaw nor big limitation). So the idea is to go for a version 1.1 rather than a 2.0.
Integration with other specs
While not part of the Bean Validation JSR, I think it is important to pursue further collaborative work with some other JSR leads on how to integrate Bean Validation into the various lifecycles of the SE/EE platforms. Certainly nobody wants each specification to invent its own validation mechanism and its own annotations. The work we did with JPA 2 and JSF 2 showed that it is possible and beneficial for the platform and developers.
- JAX-RS: call Bean Validation upon HTTP method calls on parameters. If a parameter is not valid, JAX-RS could return the appropriate HTTP error code as well as some payload describing the error.
- JAXB: some people have asked for integration between Bean Validation and JAXB. Basically, the Bean Validation constraints (at least the fundamental ones) could be converted into the XML schema descriptor (and vice versa) to guarantee a unified propagation between the Java land and the XML land. I have been exploring some of the needs with Martin Grebac and I hope we can converge.
- JPA: improve the integration by letting Bean Validation constraints influence the DDL generated with the constraints declared on the entity model
- CDI: offer a way for Bean Validation pluggable components to allow CDI style injection (in particular constraint validator implementations)
- CDI: integrate method-level validation (see below)
Method level validation
The idea is to offer APIs to validate parameters and return values of method calls. These APIs would be used by any injection or AOP framework around method invocations. If a constraint violation is detected, an exception (eg. ConstraintViolationException) would be raised.
public class OrderManager { public void processOrder(@Valid Order order, @Min(0) @Max(30) int retry) { doProcessOrder(...) } }
if Order contains constraint violations or if retry's value is not between 0 and 30, a ConstraintViolationException will be raised by the interceptor framework.
Interceptor frameworks could be:
- CDI: some stereotyped interceptor could trigger the method validations when accessed
- AOP style framework like Javassist or AspectJ
@Valid and group propagation
Some people have required the ability to translate a group into another group while cascading the validation. This can help reduce the number of groups and increase reuse.
public class Address { @NotNull String city; @Valid(from=Default.class, to=EnhancedGroup.class) Country country; } public class Country { @NotNull(groups=EnhancedGroup.class) String name; @Size(min=2, max=2, groups=EnhancedGroup.class) String iso2; }
Apply constraints on elements of collection
While we can validate constraints on the collection itself and ask to cascade validation to the elements of the collection, we cannot put constraints on the collection element itself. This is annoying for collection of native types in particular. There are several not so elegant solutions to this problem, the real solution is to wait for Annotations on Java types (JSR-308)
Collection<@NotNull String> names;
Depending on when JSR-308 finally comes out, we might want to delay this feature.
Various issues
In no particular order, here are a few issues or features we can also try to tackle.
Constraint composition
Today constraint composition is done with a logical AND (all constraints must be valid). We could also support logical OR composition.
@ConstraintComposition(OR) @SSN @TemporarySSN @Constraint(validatedBy = { }) @ReportAsSingleViolation @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) public @interface ValidSSN { String message() default "Not a valid social security number"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; }
JTA and exception propagation
In EE, there are some inconsistencies on how exceptions are raised:
- while in the process of a business method
- raised by the declarative or explicit commit() calls
Basically when operations (like validation) are triggered within the declarative commit(), everything I believe is wrapped into a RollbackException. Which means that depending when JPA's flush() is called, ConstraintViolationException (raised by JPA) comes either untainted or comes wrapped in RollbackException. I wonder if we can fix this inconsistency.
Better rules for OSGi style containers
Some extreme modularity fanboys have complained about some fuzziness in the spec around visibility and classloaders. We should clarify that.
Exclusive flag on @BigDecimal / @BigInteger
Allow to exclude limits.
ConstraintViolationException builder
The idea is to provide a simple API to build consistent ConstraintViolationExceptions. Because Bean Validation is usually called by the lifecycle of other specifications or frameworks, it is their responsibility to raise the exception.
Your participation
That's all I have. I am sure I'm missing many improvements so please speak up. You can do it however it pleases you:
- comment on this blog entry
- open an issue on the specification issue tracker
- discuss on the Bean Validation forum
And of course, you can always go one fork ahead.
From this first wave of feedback, I plan to propose a JSR to the JCP.
Note that Hibernate Validator 4.2 has or will integrate some of these features which will provide us feedback.
Emmanuel