Red Hat

In Relation To Hibernate Validator

In Relation To Hibernate Validator

You might have heard the news: JBoss AS 7 is out :) What does it mean from an Hibernate user perspective?

Before we go that way and if you are in a hurry Pete has written a few getting started guides covering JPA in JBoss AS 7. You might be interested.

Back to the subject: JBoss AS 7 and Hibernate.

Hibernate Core

First of all, JBoss AS 7 comes with Hibernate Core 4. This essentially means that AS 7 will be using the new foundational grounds for Hibernate Core. Hibernate Core 4 comes with many internal changes:

  • A new ServiceRegistry interface: many pieces of Hibernate are now service based and many contracts have been enhanced (like connections and second level caches)
  • A MetadataSources interface: instead of mixing configuration and mapping like the Configuration class was doing, we have now split the concerns and lifecycles
  • A package refactoring splitting classes into api, spi and internals: if your application depends on internals, you know you might get burnt by a minor/micro update
  • A new class loader service (see below)
  • Better logging with consistent error id (our goal is to build an error-id to solution database somewhere over time)
  • A move to Git and GitHub for version control: hopefully this is speeding up community contribution integration

Multi-tenancy

We have also introduced some new features, the most interesting definitely being multi-tenancy (see also here).

New classloader service

Why?

Historically, Hibernate relied on standard class-loading paradigms that targeted JSE and JEE deployment environments. However, with the growth of OSGi and other modular systems like JBoss AS 7, those same approaches no longer always work. So Hibernate needed a new approach that would allow it operate in all possible deployment environments.

How?

In Hibernate 4 we leverage the ServiceRegistry to define a pluggable service for providing interaction with the class-loading of the semantics of the environment in which Hibernate will be run. Specifically, the idea is to allow external entities (the user, the environment developers, etc) to define and plug in a custom scheme for class path interactions. For example, an OSGi container could choose to provide Hibernate (either directly or as its JPA provider) and install a custom service for class loader interactions to override the default one.

Hibernate Core in AS 7

JBoss AS 7 integrates with Hibernate 4.0.0.Beta1, to provide both the EE container managed JPA features and application managed access as well. The AS7 JPA subsystem integrates with Hibernate via the JPA specification SPI interfaces. In earlier releases of JBoss AS, JPA integration code was part of the EJB3 container (reflecting the evolution from EJB entity beans). Moving the JPA integration code into its own subsystem helps simplify the code and makes it easier to make changes.

Quick second-level cache tip

Enabling the (Infinispan) second level cache should be as simple as including the following in your persistence.xml file:

  <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
  <properties>
    <property name="hibernate.cache.infinispan.cachemanager" value="java:jboss/infinispan/hibernate"/>
    <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.JndiInfinispanRegionFactory"/>
  </properties>

I (aka Scott Marlow) would like to thank the following people for contributing to the JBoss AS7 JPA subsystem:

  • Stuart Douglas for contributing to the JPA subsystem.
  • Steve Ebersole for contributing to the JPA subsystem (especially Hibernate 4.0 integration).
  • Jaikiran Pai for contributing to the JPA subsystem and answering an amazing number of questions in the forums (JPA + hundreds of other topics).
  • Emmanuel Bernard for answering my never ending JPA 2.0 specification questions.
  • Carlo de Wolf for answering my questions about the EJB3 subsystem (which the new code is based on).

What is next

Improving support for applications that use a different version of Hibernate than is packaged with JBoss AS 7. The plan is to let users deploy the Hibernate jars as well as a hibernate-jbossas7 integration jar. The integration jar will be tailored to the specific couple of Hibernate / JBoss AS version (or families of).

To be clear, Hibernate native applications can already include their own version of Hibernate in JBoss AS 7 simply by including the jar in their deployment. But we want JPA applications to benefit from this enhancement as well. Because it involves specification classes, this requires a bit more work.

We will also include additional tuning options to disable some of the JPA integration (ie prevent the container from starting the persistence unit).

Hibernate Validator and Bean Validation

What's new in AS7 in relation to Bean Validation? The short answer - nothing. It was already awesome ;) The initial version - AS 7.0 - ships with Hibernate Validator 4.1.0.Final. This is the same Validator version as in AS 6 so no change there.

The long answer is that Hibernate Validator 4.2.0.Final merely missed the AS 7.0 release train and an upgrade is planned at the latest in AS 7.1. What will the update mean for AS users? Besides the usual bug fixes and performance improvements, the biggest new feature is the implementation of appendix C of the Bean Validation specification: method level validation.

With this API a design by contract approach is possible which can already be seen in action in the Seam Validation module. Another new feature is the ability to combine the composing constraints with AND and OR operators. There is also a fail fast mode in which validation stops on the first validation error and a new message interpolator which is able to interpolate the validated value.

As you can see AS 7.0 is just the beginning. More is to come in the coming releases...

Hibernate Search

We are working on Hibernate Search 4 which will be compatible with Hibernate Core 4. As a matter of fact, we have already published a compatible version via a Maven SNAPSHOT but expect a first alpha release soon.

Hibernate Search 4 is our chance to fix mistakes from the past. To be honest, the codebase and concepts have aged quite well despite the massive feature shifts we have done in Hibernate Search. Anyways, we are doing some changes including splitting API/SPI/implementations to help people discover when they use a class that is subject to change.

We are also working on a new per index manager to better use some of the new features and design changes of Lucene. This will give you more flexibility on how to index data on a per entity level (sync/async etc).

And remember, go try the blazingly fast, lightweight, modular, hot and incremental deployable, elegantly administrable, domain manageable, first class best of breed JBoss Application Server 7

Happy code/fast deploy/test cycles :)

Steve, Hardy, Scott Marlow and Emmanuel

Hibernate Validator 4.2.0.CR1

Posted by    |       |    Tagged as Bean Validation Hibernate Validator

Hibernate Validator 4.2.0.CR1 is finally ready for download via the JBoss Maven Repository or SourceForge. We promise you won't have to wait so long for 4.2.0.Final. In total we addressed 28 issues. Most of the issues where minor bug fixes, documentation and code refactorings. Thanks you everyone providing bug reports and helping us to make Validator even better :-)

The biggest change is the ability to now also configure method level validation programmatically. To implement this in an unambiguous way we had to make yet some more changes to the programmatic API. Remember how the programmatic API looked like in Beta2? Here is an example:

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .property( "manufacturer", FIELD )
        .constraint( NotNullDef.class )
    .property( "licensePlate", FIELD )
        .constraint( NotNullDef.class )
        .constraint( SizeDef.class )
            .min( 2 )
            .max( 14 )
    .property( "seatCount", FIELD )
        .constraint( MinDef.class )
            .value ( 2 )
.type( RentalCar.class )
    .property( "rentalStation", METHOD)
        .constraint( NotNullDef.class ); 

With the CR1 API the same example looks like:

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .property( "manufacturer", FIELD )
        .constraint( new NotNullDef() )
    .property( "licensePlate", FIELD )
        .constraint( new NotNullDef() )
        .constraint( new SizeDef()
            .min( 2 )
            .max( 14 ) )
    .property( "seatCount", FIELD )
        .constraint( new MinDef()
            .value ( 2 ) )
.type( RentalCar.class )
    .property( "rentalStation", METHOD )
        .constraint( new NotNullDef() ); 

As you can see the difference is that you now have to instantiate the definition classes. That's all. Not too bad, right? Programmatic method level validation looks like this:

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .method( "drive", String.class, Integer.class )
        .parameter( 0 )
            .constraint( new NotNullDef() )
            .constraint( new MinDef().value ( 1 ) )
        .parameter( 1 )
            .constraint( new NotNullDef() )
        .returnValue()
            .constraint( new NotNullDef() )
    .method( "check" )
        .returnValue()
            .constraint( new NotNullDef() );   

You find the full change log for this release here. Please provide feedback via the Validator Forum and the Jira issue tracker.

Thanks to Gunnar and Kevin to once more were driving most of the work.

Enjoy!

P.S. If you have any opinion what should go into Bean Validation 1.1 let us know!

Hibernate Validator 4.2.0.Beta2

Posted by    |       |    Tagged as Bean Validation Hibernate Validator

Hibernate Validator 4.2.0.Beta2 is bottled up and ready for consumption via the JBoss Maven Repository or SourceForge.

Since Beta1 we have been focusing on method level validation details and bug fixes. One important issue in this regard is HV-421 which defines the behavior of parameter constraint validation. Generally a logical AND is used to combine all constraints defined within a class hierarchy on a given field or method. Doing the same for method parameter constraints, however, causes ambiguities with the definition of Programming by contract where subtypes may only weaken preconditions defined by supertypes. In order to support this one would have to combine all parameter constraints within a hierarchy using an OR. A conservative alternative (the one we chose for this release) is to prohibit multiple parameter constraints on the same parameter within a class hierarchy. HV-421 discusses in more detail. We are very interested in feedback on this.

Another method level validation related feature is the extension of the meta data API (HV-440). We introduced three more interfaces TypeDescriptor, MethodDescriptor and ParameterDescriptor which you can all find in the org.hibernate.validator.method.metadata package. Here is an usage example:

 MethodValidator validator = Validation.byProvider( HibernateValidator.class )
    .configure()
    .buildValidatorFactory()
    .getValidator()
    .unwrap( MethodValidator.class );

TypeDescriptor typeDescriptor = validator.getConstraintsForType( clazz );
...
Set<MethodDescriptor> constrainedMethods = descriptor.getConstrainedMethods();
...
List<ParameterDescriptor> parameterConstraints = methodDescriptor.getParameterConstraints();
ParameterDescriptor parameterDescriptor = parameterConstraints.get( 0 );
assertTrue( parameterDescriptor.hasConstraints() );
...
Note: MethodValidator.validateParameters was renamed into MethodValidator.validateAllParameters (HV-415).

To mention at least one method level validation unrelated feature - Hibernate Validator has now a fail fast option. When enabled, validation will terminate on the first validation error. This could be interesting for large object graph validation. You can enable the fail fast flag for example via:

ValidatorFactory factory = Validation.byProvider( HibernateValidator.class )
                             .configure()
                             .failFast( true )
                             .buildValidatorFactory();
You find the full change log for this release here. Please provide feedback via the Validator Forum and the Jira issue tracker.

Enjoy!

P.S. For all the Seam people out there. Gunnar started a new Seam 3 module called SeamValidation which offers amongst other a CDI extension for method level validation. Check it out!

P.P.S. Make sure to also provide feedback on what we should include into Bean Validation 1.1

Vote for Pedro

Posted by    |       |    Tagged as Bean Validation Hibernate Validator

Well not really ;)

We have talked about Gunnar and Kevin that have and are still doing an awesome job on Hibernate Validator, especially for the last release and the current one in development. Please consider voting for them for the JBoss.org recognition awards.

Gunnar Morling is nominated in the:

The new method validation feature is all his for example.

And Kevin Pollet is nominated in the:

He fixed many bugs but also added some nice cool features like Joda-time support.

Yyou probably don't know it yet but Hibernate Core and Hibernate Validator source code is now on Git and Hibernate Search and co will likely follow very soon. There are various reasons for the move but to summarize it, life was not bad under SVN but it's really great under Git.

Getting Hibernate sources

The public reference Git repository is hosted at GitHub. We are not married to GitHub but so far, we really like the infrastructure they offer. Kudos to them! In any case moving is one clone away. That tends to keep services like that on their toes.

Hibernate Core is here while Hibernate Validator is there.

Contributing

If you want to contribute a fix or new feature, either:

  • use the GitHub fork capability: clone, work on a branch, fork the repo on GitHub (fork button), push the work there and trigger a pull request (pull request button). Also see http://help.github.com/forking and http://help.github.com/pull-requests
  • use the pure Git approach: clone, work on a branch, push to a public fork repo hosted somewhere, trigger a pull request git pull-request
  • provide a good old patch file: clone the repo, create a patch with git format-patch or diff and attach the patch file to JIRA

Our preference is GitHub over pure Git over patches:

  • GitHub lets us comment on your changes in a fine grained way
  • Git generally leads to more small commits that are easier to follow
  • a big fat patch of 100k is always depressing and can't be updated easliy

If you still want to do it the old way a provide a patch file, that's ok too.

Various tips on Git

While in no way comprehensive, here are a collection of useful tips when using Git.

Read a book on it

The time will be worth it. I particularly enjoyed Pro Git. It's an awesome book and very practical. It has a free html and epub version (buying the tree version is recommended to repay the author).

Cloning

Prefer the git protocol when cloning over http (so say the experts). At the very least that will be much faster. cloning the repo from GitHub took me less than 3 minutes.

#for people with read/write access
git clone git@github.com:hibernate/hibernate-core.git

#for people with read-only access
git clone git://github.com/hibernate/hibernate-core.git

This will create a remote link named origin. I usually tend to rename it to reflect what it really is.

git remote rename origin core-on-github

Note that you can attach more than one remote repository to your local repository

git clone git://github.com/hibernate/hibernate-core.git
git remote rename origin ref-core-github
git remote add manu-core-github git@github.com:emmanuelbernard/hibernate-core.git
git fetch manu-core-github

Pushing and pulling

To initially get a copy of a remote branch locally, do

git checkout -b 3.6 origin/3.6

When pulling a branch, it's best to keep the same name between the origin repo and your clone. Many syntax have shortcuts in this situation (are you listening Hardy? ;) ). You can then do

git push origin master

If you happen to have renamed the branch master to say local-master locally, do

git push origin local-master:master

To delete a branch on a remote repository, you push an empty one

git push origin :branch-to-remove

Branches

Always work on a topic branch and merge your work when you are done.

git checkout master
git checkout -b HHH-XXX
#hack commit hack commit

Don't forget to pull from your master and rebase this topic branch before proposing request pull.

There are many advantages to this, one of them being that you can work on many different things in parallel and sync them with the reference master easily.

Likewise if you want to share a work with somebody from the Hibernate team, push to the public repo and define the pull request of your topic branch. Make sure your topic branch is above the most recent master.

Commits

Prefer small commits, they will be more readable and will very unlikely fail on merge.

Write good comments (one short line including the issue number at stake and a summary, followed by a blank line and a more detailed explanation if needed.

HHH-XXX Fix NPE on persist

Fix stupid bug by Gavin that lead to a NPE when persisting objects with components

Merge or rebase

It's a debate, but here is my take on it.

  • Primitive 0: DO NOT rebase a branch that you have shared publicly (unless you know people won't use it or you wish them harm).
  • Primitive 1: Prefer rebase over merge assuming it does not break Primitive 0

This is particularly sensible when you trigger a pull request: rebase atop the branch you are branching of (master usually). Your work will be easier to read and integrate.

Rebase put changes from the branch you forked (say master) below the new commits you have done (say HHH-XXX) and thus keep the history linear.

git checkout HHH-XXX
git rebase master

While we are at rebasing, you can rewrite your commit history to clean comments or merge some commits together (aka squashing)

git rebase -i HEAD~6 (go back 6 commits in time)

Backporting: cherry-picking

Git made backporting fun.

Say you have done some commits on master and the sha1 of the commits are ae397d... and 87ab342...

You can apply them on an older branch very easily.

git checkout 3.5
git cherry-pick ae397d
git cherry-pick 87ab34

Bam, you're done. Now did I tell you to do small commits? That's also for the backporters.

Aliases and configuration

Once you're fed up with typing longish command lines, use aliases. I've put a copy of my ~/.gitconfig file in case people want to copy some things including aliases (see below)

~/.gitconfig
[user]
     name = Redacted
     email = redacted@redacted.com
     signingkey = id_key.pub
[core]
     editor = open -nW -a Smultron
[merge]
     tool = opendiff
[color]
     ui = auto
[color "branch"]
     current = yellow reverse
     local = yellow
     remote = green
[color "diff"]
     meta = yellow bold
     frag = magenta bold
     old = red bold
     new = green bold
[color "status"]
     added = yellow
     changed = green
     untracked = cyan
[github]
     user = redacted
     token = redacted
[alias]
     co = checkout
     undo = reset --hard
     cb = checkout -b
     br = branch
     cp = cherry-pick

Tools

If you use Mac OS X, GitX is a fantastic tool. In particular, you can very easily play with interactive staging and commit only some parts of a file in a couple of clicks. A typical use case is to separate the commit of a typo from the commit of a core feature. Some people like the built-in GitK GUI.

Command completion support via git-completion.bash is pretty good if you are command shell type person. The script is available in the Git project sources and in other places (including Fedora). Pro Git has some more information on it.

Various

You can also read this blog entry that was some more info for people moving from SVN to Git.

This entry is too long already, feel free to add your tips in the comments.

At JavaOne this year, I gave a more advanced presentation than usual on how to use Bean Validation. A few folks have asked me to share it and there it is.

A bit of warning though, this is a presentation that is best seen live as I talk a lot on my slides and even more during the live demo. I am not the kind of person that reads its slides and the demo part is probably about 50% of the presentation so if you can see Hardy or me doing this presentation live, by all means go.

But in the mean time, here are the slides BeanValidationBestPractices-1.0.pdf[1]. I have also put the demo code on a git repository. Simply do

//retrieve the GIT repository
git clone http://emmanuelbernard.com/various/presentations/beanvalidation-bestpractices/beanvalidation-bestpractices.git bv-bp
cd bv-bp

//checkout the demo when starting
git checkout -b demo-start-branch demo-start-state

//checkout the demo when done
git checkout -b branch-demo-done demo-done-state

//hack

I've defined two tags:

  • demo-start-state which correspond to the demo when I start working on it on stage
  • demo-done-state which correspond to the demo when I am done and leave the stage

I have left a bunch of TODOs in the start state and described what I do in a txt file at the root, you should be able to follow.

Enjoy

Gunnar asked me an interesting question on Bean Validation. Instead of keeping the knowledge private, I thought it would be useful to share more wildly.

Is it possible to determine whether a given constraint is specified at field or property level using the constraint metadata API?

First off, in many case you don't need to do the distinction. Had Java support properties from the ground up, we would not have this problem (sigh).

Anyways, the answer is yes. You can fine tune what is returned from the metadata API.

PropertyDescriptor property = 
    validator.getConstraintsForClass(Address.class)
               .getConstraintsForProperty("street1");

Set<ConstraintDescriptor<?>> fieldConstraints =
    property
        .findConstraints()
            .lookingAt(Scope.LOCAL_ELEMENT)
            .declaredOn(ElementType.FIELD)
            .getConstraintDescriptors();

Set<ConstraintDescriptor<?>> propertyConstraints =
    property
        .findConstraints()
            .lookingAt(Scope.LOCAL_ELEMENT)
            .declaredOn(ElementType.METHOD)
            .getConstraintDescriptors();

The key here is the use of the findConstraints() fluent API. You have three ways to restrict the metadata retrieved:

  • declaredOn(ElementType... types): defines where to look the constraints (METHOD, FIELD etc)
  • lookingAt(Scope scope): defines whether to look for constraints hosted on superclass/interfaces (default) or not
  • unorderedAndMatchingGroups(Class<?>... groups): restrict to the constraints matching a given set of groups for this element (note that the ordering of group sequences is not respected)

That's all.

There are no functional changes between CR1 and this Final release. Some minor issues in the @Min, @Max and @EmailValidator got fixed (HV-335, HV-339) as well as some documentation typos. We also spend some time improving the parsing and validation speed by reviewing and improving some reflection based code (HV-340, HV-341, HV-342). Review the full release notes for details.

Download as usual either from the JBoss Maven repo or from SourceForge.

There are already several issues on the 4.2 roadmap, but we are welcoming ideas and suggestions for the next release on the Validator Forum. One of the major new features will most likely be method-level validation (as specified in Appendix C of the Bean Validation specification) as well.

Stay tuned!

Amendment: Gunnar did a great job summarizing the new features of Hibernate Validator 4.1 on his blog. And of course we covered already most of the new features here as well. See programmatic constraint configuration, ResourceBundleLocator and @ScriptAssert.

Hibernate Validator 4.1.0.CR1

Posted by    |       |    Tagged as Hibernate Validator

Hibernate Validator 4.1.0.CR1 is now available. This is the last milestone build before the Final release. Not much has happened between Beta2 and CR1. The programmatic API as described in the previous release blog entry stayed as is and there were only three minor bug fixes. See release notes for details.

Download as usual either from the JBoss Maven repo or from SourceForge.

Ideas and suggestions are welcome on the Validator forum. Let us know what you want to see in Validator post 4.1.0. In case you find a bug create a jira issue in HV.

Enjoy!

Hibernate Validator 4.1.0.Beta2 is out. A total of 29 issues got resolved since the last release and you can review then in the Jira changelog. Amongst others we added the @ScriptAssert constraints as promised in the previous release blog. Initially we wanted to release 4.1.0.CR directly, but we added a new programmatic constraint configuration API (HV-274) for which we want to first gather some feedback.

The new API is centered around ConstraintMapping which is the entry point to a fluent API allowing the configuration of constraints. The API is comparable to the one described in Emmanuel's blog Hibernate Search Programmatic Mapping API. But let's look at an example:

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .property( "manufacturer", FIELD )
        .constraint( NotNullDef.class )
    .property( "licensePlate", FIELD )
        .constraint( NotNullDef.class )
        .constraint( SizeDef.class )
            .min( 2 )
            .max( 14 )
    .property( "seatCount", FIELD )
        .constraint( MinDef.class )
            .value ( 2 )
.type( RentalCar.class )
    .property( "rentalStation", METHOD)
        .constraint( NotNullDef.class );

As you can see you can configure constraints on multiple classes and properties using method chaining. The constraint definition classes NotNullDef, SizeDef and MinDef are helper classes which allow to configure constraint parameters in a type-safe fashion. Definition classes exists for all built-in constraints in the org.hibernate.validator.cfg.defs package. For a custom constraint you can either create your own definition class extending ConstraintDef or you can use GenericConstraintDef (we are also thinking about providing another annotation processor which at compile time could generate the required helper classes):

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .property( "licensePlate", FIELD )
        .constraint( GenericConstraintDef.class )
            .constraintType( CheckCase.class )
            .param( "value", CaseMode.UPPER );

Last but not least, you can also define cascading constraints as well as the default group sequence of an entity.

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .valid( "driver", FIELD )
.type( RentalCar.class)
    .defaultGroupSequence( RentalCar.class, CarChecks.class );

Since the programmatic configuration is not part of the official Bean Validation specification you will have to get hold of HibernateValidatorConfiguration during the bootstrapping process in order to set your ConstraintMapping:

HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();
config.addMapping( mapping );
ValidatorFactory factory = config.buildValidatorFactory();
Validator validator = factory.getValidator();

WDYT? Is this API useful? Easy to use? Anything we should consider/change?

If you want to play with this release, you can download it from the JBoss Maven repo or from SourceForge.

Enjoy!

back to top