I'm the person behind annotations in Hibernate: Hibernate Annotations, Hibernate EntityManager, Hibernate Validator and Hibernate Search. I am a member of the JPA 2.0 expert group as well as the JSR-303 Bean validation spec lead. You can check out my book Hibernate Search in Action by Manning.
19. Jun 2014
17. Apr 2014
12. Dec 2013
05. Dec 2013
25. Jul 2013
28. May 2013
21. Mar 2013
16. Jan 2013
07. Nov 2012
03. Oct 2012
28. Jun 2012
01. May 2012
04. Apr 2012
15. Mar 2012
14. Mar 2012
This post is about validation, Bean Validation specifically. And the what it solves. It is a reaction to a post by Julien Tournay which basically claims - if I sum it up - that:
- Scala is faster than Java (he is coming from far far away on that one - du diable vauvert as we say in French)
- Bean Validation is kind of crap
- The new Play Unified Validation API is awesome
I usually am old and wise enough not to answer these kind of posts. But I want to feel the blood of my youth again damn it! After all I am from an era when The Server Side was all the rage, trolls had real teeth, things were black or white. That was good fun.
You missed the point like Mars Climate Orbiter title?
With a sensationalist title like
Scala is faster than Java, I had to step up my game.
Plus Mars Climate Orbiter missed Mars due to a conversion error
and we will talk about conversion today.
I won't refute things point by point but rather highlight a few fundamental misunderstandings and explain why things are like they are in Bean Validation and why it makes sense.
IMHO, @emmanuelbernard a créer son API avec les outils a sa disposition - @skaalf
IMHO, @emmanuelbernard has created his API with the tools he had at his disposal - @skaalf
We certainly pushed the boundaries of Java when both CDI and Bean Validation were designed and I wished I had more freedom here and there. But no Bean Validation is like it is because that's the most natural way validation is expressed in the Java ecosystem for what we wanted to achieve. It is no good to offer something that does not fit into the ecosystem.
For example, in Java, people use mutable objects.
Mutable believe it or not is not a swear word in this language.
My understanding is that Play Unified Validation API makes use of Scala's community incline for immutability.
In the use case Julien takes as an example, a JSON string is unmarshalled, conversion is applied (for dates - darn JSON) and then values are validated. He considers it weird that Bean Validation only does the latter and finds the flow wrong.
We kept this separation on purpose. The expert group vastly agreed that Bean Validation was not in the business of conversion and that these steps ((un)marshalling, conversion, validation) should be separated. Here is a key reason:
- marshalling and conversions are only at the Java boundaries (Web frameworks, services enpoints, datastores enpoints, etc)
- validation happens both at these boundaries but also at key lifecycle events within the Java boundaries
Conceptually, separating validation from the rest makes a lot of sense to enable technology composition and avoid repetitions - more on that latter point later. What is important is that for a given boundary, they are properly integrated. It's not unlike inlining in compilation.
One key point in the design of Bean Validation is that it has been built to be integrated within a cohesive stack more than to be used individually.
JPA transparently calls Bean Validation on your objects at the right time. JSF calls Bean Validation transparently before populating the beans. JAX-RS calls Bean Validation on the inbound and outbound resources transparently. Note that these three technologies do address the marshalling and conversion problem already. That's their job.
So the key is that an application rarely has to call the Bean Validation API. I consider it a failure or an unfinished work when it has to.
If you need to explicitly validate some piece of data in a fire and forget way, Bean Validation might not be the best tool. And that's OK.
Back to the JSON case. When the JSON Binding spec will be out, we will have the same integration that is currently present in Play Unified parsing, conversion and validation API (it could also be done today in Jackson, I'm not sure what extension points this library offers). While the three layers marshalling / conversion / validation will be conceptually separated - and I'm sure will report different types of error for better tracking - the implementation will use some specific APIs of Bean Validation to inline validation with the unmarshalling and conversion. That API exists BTW, it is Validator.validateValue which lets you validate a value without creating the POJO associated. It is used by web frameworks already. Pretty much what Play Unified Validation API does.
As for JAX-B and XML binding, well let's say that there is an X in it and that it's not safe for children. More seriously, we have integration plans with mapping between the XSD and the Bean Validation constraints but we haven't got around to do it yet.
From what I see of the Play Unified Validation API, you put the declaration / implementation of the validation next the marshalling logic. In other words you cannot share the constraint declaration between different marshalling operations or even between object transformations.
And that's future proof, when we add JSON-B support, boom the constraints already declared are used automatically and for free.
Bean Validation cannot be understood if you take it in isolation. It is useful and works in isolation for sure but it shines when integrated in a platform from top to bottom. We did and keep doing it in Java EE but we also make sure to keep our APIs and SPIs open for other platforms to do the same. Spring famously has been doing some of it.
Let's mention a few key features of Bean Validation that are not addressed at all in Play's approach:
- constraint inheritance
- method validation
- custom and context sensitive programmatic error report
- partially valid object graph - yes that's important in a mutable world
Even a few of these would make Play's stuff much much different.
Now with this context properly set, if you read back Julien's complaints about Bean Validation (especially about they design), they fall one by one pretty much. I have to admit their composition approach is much nicer than Bean Validation's which relies on annotated annotations. That's the main thing I miss.
Design is choice. Without knowledge to the designer's choices, you can too easily misunderstand her design and motives. Julien has been comparing Apples with Oranges, which is ironic for someone working on one of the most type-safe language out there :o)
But it's good that more people take data validation holistically and seriously and step up the game. Less work for app developers, safer apps, happier customers. Judging by the location, I could even share some thoughts over a few rounds of whisky with Julien :)
Time for a new release of Hibernate OGM.
On the new feature side, we have added integration modules for both:
But the bulk of the work has been around polishing and fixing issues based on your feedback. In a nutshell, we polished MongoDB's support (security, native queries) and Neo4J. We fixed a few bugs around collections and query support. We kept improving the option framework which we use to define backend specific behaviors.
Many thanks to all the contributors that made this release possible whether it be via pull requests, bug reports or feedback on the forum.
One of the benefit of rewriting our Hibernate website is that we made our roadmaps more prominent. And in case of Hibernate OGM, we had to write it :)
Hibernate OGM, in a nutshell, is JPA for NoSQL backends (more here).
Gunnar and Davide have made significant forays into the feature set we wanted for our first stable version. This has made writing the roadmap much easier. You can get all the (up to date) details on Hibernate OGM's roadmap page. Here I will sum up what is between us and our first final version.
Option system: offer ability to define per property, per association, per entity or global options. Offered via annotations and via a programmatic API. This system will enable declarative denormalization, specific backend optimization settings and so on.
CouchDB support: offer CRUD support for CouchDB
Performance check: we keep a eye on them but a dedicated round of optimization will happen.
Better navigation with Neo4J: our initial mapping works but we know we can access associations in a faster way.
Batch changes: use the backend batching capability if it exists.
query support for known backends: add our current query support for Neo4J and CouchDB as much as possible.
cache query plans: it's all in the title :) Hibernate ORM already does that, we need to catch up.
I'm sure we will have to chop off a few additional tasks here and there but our goal is to stay focused on these as much as we can.
hibernate.org has been completely revamped.
The entire team has been working on it for a long time. I am personally very happy to see this puppy out.
Our goals were:
- to help newcomers understand what each Hibernate project is about and why it matters
- to help regular / advanced users to find what they are looking for quickly
- to give higher visibility to what mattered most
- to clarify the fact that Hibernate is an umbrella of (awesome) projects
The infrastructure is also much easier and flexible (you can even contribute pull-requests to fix typos or improve the site). You will see additional improvements over the coming months. Especially around better integrated documentation.
Let us know what you think and of any glitch you might see.
Now on to hibernate.org and enjoy.
The voting for the JBoss Community Recognition Awards 2013 ends tomorrow; if you haven't done it yet please vote for our contributors.
Among other amazing contributors, some have done amazing work on Hibernate projects and we think they deserve a special recognition:
Guillaume Smet has been thoroughly testing Hibernate Search, and providing many critical fixes. His contributions have been priceless and he also regularly contributes to the mailing list with great advice. Not least, he motivates us all to put the quality bar higher at every release.
Łukasz is always willing to dig in and tackle difficult issues spanning a wide breadth of topics -- especially ones outside the scope of his typical expertise. His help in resolving many issues in the Hibernate database testing matrix really illustrates how reliably amazingly his contributions have been. These were mostly databases where we could not offer him the greatest tooling (often not even database access to databases being tested). Those were contributions that directly affected Hibernate and EAP timelines in very positive ways. And all of that in addition to maintaining Envers...
Guillaume Scheibel looks like a full time Hibernate team member. He has been leading the development for the MongoDB GridDialect for Hibernate OGM, developed most of it himself, and participates in design decisions. The need for Hibernate OGM to have a MongoDB/Infinispan integration to complete query support was reason enough for him to implement one and contribute it to Infinispan. Not least, he presented the project at JUG events!
Nicolas proposed a great new feature to the Hibernate Search project: spatial queries and proximity filtering. He lead the design of it in the most collaborative way with the team, donated his expertise in spatial coordinates handling, spent months to implement it and polish it considering feedback from the whole community, and a year later is still actively helping new users with it, improving documentation and taking ownership of bug reports.
Tim's expertise, help, advice and support were instrumental in getting OSGi support into Hibernate. As an Apache Aries PMC member and Enterprise OSGi advocate, Tim has a wealth of knowledge; but his patience and knack for doing a great job at explaining the concepts were what made him truly amazing to work with. Without Tim's help OSGi support in Hibernate would still be a talking point rather than an implemented reality.
|Showing 1 to 5 of 96 blog entries||