Help

I'm the person behind annotations in Hibernate: Hibernate Annotations, Hibernate EntityManager, Hibernate Validator and Hibernate Search. I am a member of the EJB 3.0 expert group as well as the JSR-303 Bean validation spec lead.

My latest annotations thing is Hibernate Search : an Hibernate/Apache Lucene integration letting search domain model objects in free form (google or yahoo like) without hassle.

I am also co-writing Hibernate Search in Action already available in early access program.

Location: EST
Occupation: Core developer at JBoss, a division of Red Hat
Archive
My Links
Bean Validation: validation everywhere EE 6 edition
03. Dec 2009, 16:02 CET, by Emmanuel Bernard

Now that Bean Validation is officially part of Java EE 6 and that Java EE6 is officially voted YES, let's see how Bean Validation integrates with the rest of the eco system.

What is Bean Validation

It's goal is to let application developers declare their data constraints once by annotating their model and make sure these constraints are validated by the different layers of the application in a consistent manner. Without Bean Validation, people have to write their validation rules in their favorite presentation framework, then in their business layer, then in their persistent layer, to some degree in the database schema and keep all of them synchronized.

Here is how this centralized constraint declaration looks like:

class User {
  @NotEmpty @Size(max=100)
  String getLogin() { ... }

  @NotEmpty @Size(max=100)
  String getFirstname() { ... }
  
  @Email @Size(max=250)
  String getEmail() { ... }
  ...
}

There are many more features like constraint composition, grouping but let's focus on how Bean Validation integrates with the EE 6 stack.

So what do I have to do to make it work in Java EE 6

The short answer is nothing. Not even an XML configuration trick.

Simply add your constraints on your domain model and the platform does the rest for you.

JSF and how to expose constraint violations to the user

In JSF, you bind form inputs to properties of your domain model. JSF 2 and Bean Validation smartly figure out which property you are binding to and execute the constraints associated to it.

<h:form id="register">
    <div style="color: red">
        <h:messages id="messages" globalOnly="true"/>
    </div>

    <div>
        Login:
        <h:inputText id="login" value="#{identifier.user.login}"/>
        <h:message style="color: red" for="login"/>
        <br/>
        Password:
        <h:inputSecret id="password" value="#{identifier.user.password}"/>
        <h:message style="color: red" for="password"/>
        <br/>
        Firstname:
        <h:inputText id="firstname" value="#{identifier.user.firstname}"/>
        <h:message style="color: red" for="firstname"/>
        <br/>
        Email:
        <h:inputText id="email" value="#{identifier.user.email}"/>
        <h:message style="color: red" for="email"/>
        <br/>

        <h:commandButton id="Login" value="Login" action="#{identifier.register}"/>
        <br/>
        <h:button id="cancel" value="Cancel" outcome="/home.xhtml"/>
    </div>
</h:form>

If the email, for example is malformed and the first name is left empty, Bean Validation will return the constraint violations to JSF 2 that will expose them to the user in a localized error message. By default, it just works and you don't even have to think about it.

For more advanced use cases, like disabling constraint validation for one or several fields or using a specific group or set of groups instead of the default one, you can use the <f:validateBean/> tag (check line 8 and 20 in the following example).

<h:form id="register">
    <div style="color: red">
        <h:messages id="messages" globalOnly="true"/>
    </div>

    <div>
        <!-- ***** use a specific group ***** -->
        <f:validateBean validationGroups="${identifier.validationGroups}">
            Login:
            <h:inputText id="login" value="#{identifier.user.login}"/>
            <h:message style="color: red" for="login"/>
            <br/>
            Password:
            <h:inputSecret id="password" value="#{identifier.user.password}"/>
            <h:message style="color: red" for="password"/>
            <br/>
            Firstname:
            <!-- ***** disable validation for firstname ***** -->
            <h:inputText id="firstname" value="#{identifier.user.firstname}">
                <f:validateBean disabled="true"/>
            </h:inputText>
            <h:message style="color: red" for="firstname"/>
            <br/>
            Email:
            <h:inputText id="email" value="#{identifier.user.email}"/>
            <h:message style="color: red" for="email"/>
            <br/>

            <h:commandButton id="Login" value="Login" action="#{identifier.register}"/>
            <br/>
            <h:button id="cancel" value="Cancel" outcome="/home.xhtml"/>
        </f:validateBean>
    </div>
</h:form>

In the future, we want to work with RichFaces so that the constraints declared on the object model are validated in the JSF components on the client side. This is something we had prototyped already and that Pete, Dan and I proposed to the JSF 2 expert group initially but we had to scale down our ambitions :) Expect some innovations from us in this area.

But not all your data comes from the presentation layer.

JPA 2: last line of defense

Again, by default, your JPA 2 provider runs Bean Validation on the entities you are about to persist or update. You are then guaranteed to not put invalid data in your database and thus increasing the quality of your data overall. Oh, and these are the same constraints you would have validated in JSF 2.0.

You can disable validation in JPA 2 using the validation-mode element in persistence.xml or the javax.persistence.validation.mode property and set them to none. More interestingly, you can chose which group will be validated upon entity persist, update and even delete operations. By default, the Default group is validated when you persist or update entities. Use any one of these properties to adjust that.

<property name="javax.persistence.validation.group.pre-persist" 
        value"javax.validation.groups.Default, com.acme.model.Structural"/>
<property name="javax.persistence.validation.group.pre-update" 
        value"javax.validation.groups.Default, com.acme.model.Structural"/>

<property name="javax.persistence.validation.group.pre-delete" 
        value"com.acme.model.SafeDestruct"/>

Hibernate Core and Hibernate Validator go a bit beyond that and propagate the constraints to the database schema (provided that you let Hibernate Core generate or update the schema for you). Simply set the hibernate.hbm2ddl.auto property to create, update or create-drop.

How about my service layer

You can inject a Validator or ValidatorFactory instance in any injectable POJO in Java EE 6.

class SalesService {
  @Inject Validator validator;
  @Inject @Current User user;

  public boolean canBuyInOneClick() {
    return validator.validate(user, BuyInOneClick.class).size() == 0;
  }

Where can I try it?

All of this is now available in JBoss AS 6 M1 that have just been released. Enjoy!

Hibernate Search 3.2: programmatic mapping API
02. Dec 2009, 14:35 CET, by Emmanuel Bernard

One of the innovations we have brought to Hibernate Search is an alternative way to define the mapping information: a programmatic API.

The traditional way to map an entity into Hibernate Search is to use annotations. And it's perfectly fine for 95% of the use cases. In some cases though, some people had had a need for a more dynamic approach:

  • they use a metamodel to generate or customize what is indexed in their entities and need to reconfigure things either on redeployment or on the fly based on some contextual information.
  • they ship a product to multiple customers that require some customization.

What people asked for: the XML Way(tm)

For a while, people with this requirement have asked for an XML format equivalent to what annotations could do. Now the problem with XML is that:

  • it's very verbose in it's way to duplicate the structural information of your code
<class name="Address">
  <property name="street1">
    <field>
      <analyzer definition="ngram"/>
    </field>
   </property>
   <!-- ... -->
</class>
  • while XML itself is type-safe, XML editors are still close to stone age, and developers writing XML in notepad are unfortunately quite common
  • even if XML is type-safe, one cannot refactor the Java code and expect to get compile time errors or even better automatic integrated refactoring. For example, if I rename Address to Location, I still need to remember to change this in my xml file
  • and finally, dynamically generating an XML stream to cope with the dynamic reconfiguration use case is not what I would call an intuitive solution

So we took a different road.

What they get: a fluent programmatic API

Instead of writing the mapping in XML, let's write it in Java. And to make things easier let's use a fluent contextual API (have intuitive method names, only expose the relevant operations).

SearchMapping mapping = new SearchMapping();

mapping
    .analyzerDef( "ngram", StandardTokenizerFactory.class )
        .filter( LowerCaseFilterFactory.class )
        .filter( NGramFilterFactory.class )
            .param( "minGramSize", "3" )
            .param( "maxGramSize", "3" )

    .entity(Address.class)
        .indexed()
        .property("addressId", METHOD)
            .documentId()
        .property("street1", METHOD)
            .field()
            .field()
                .name("street1_ngram")
                .analyzer("ngram")
        .property("country", METHOD)
            .indexedEmbedded()
        .property("movedIn", METHOD)
            .dateBridge(Resolution.DAY);

As you can see, it's very easy to figure out what is going on here. But something you cannot see in this example is that your IDE only offers the relevant methods contextually. For example, unless you have just declared a property(), you won't be able to add a field() to it. Likewise, you can set an analyzer on a field, only if you are defining a field. It's like the dynamic languages fluent APIs be better ;)

The next step is to associate the programmatic mapping object to the Hibernate configuration.

//in Hibernate native
Configuration configuration = ...;
configuration.setProperty( "hibernate.search.mapping_model", mapping );
SessionFactory factory = configuration.buildSessionFactory();
//in JPA
Map<String,String> properties = new HashMap<String,String)(1);
properties.put( "hibernate.search.mapping_model", mapping );
EntityManagerFactory emf = Persistence.createEntityManagerFactory( "userPU", properties );

And voila!

Extensibility

The beauty of this API is that it's very easy for XML fan boys to create their own XML schema descriptors and use the programmatic API when parsing the XML stream. More interestingly, an application can expose specific configuration options (via a simple configuration file, a UI or any other form) and use this configuration to customize the mapping programmatically.

Please give this API a try, tell us what works and what does not, we are still figuring out things to make it as awesome as possible :)

Download

Many thanks to Amin Mohammed-Coleman for taking my half done initiative and polishing it up.

You can get Hibernate Search 3.2 Beta 1 here, the complete API documentation is present in the distribution; chapter 4.4.

EE 6 tsunami
18. Nov 2009, 01:53 CET, by Emmanuel Bernard

I have been at a few conferences lately and the EE 6 wave is taking a bunch of people by surprise. Tsunami level 6. The last two examples are W-JAX and Devoxx.

Devoxx

The Java EE 6 university talk was packed. And when you know the capacity of Devoxx's rooms that's really impressive! Kudos to Antonio and Alexis for managing expectations during they lecture.

The JSF 2 and the Java EE 6 BoFs were basically full as well.

W-JAX

Keynote on Java EE 6, full day tracks on EE 6 and EJB: full. An EJB session full, WTF? What's going on?

What we are seeing is Java EE 6 and its Web profiles are becoming the hot topic of the day. If I was a proprietary web application stack, in Java or not, I would be very scared:

  • JSF 2 becomes actually usable
  • CDI (JSR-299) brings injection, context management and framework portability across the SE and EE platforms
  • Bean Validation integrates validation from the presentation down to the data layer
  • JAX-RS is simply awesome when you want to expose REST APIs
  • EE 6 looks like a platform designed by a single person, heresy!

and many more features are invading the EE landscape.

Disclaimer

I know it sounds like a blog written by some marketing borg but I have a few counter arguments to that:

  • did you see any forward-looking statement in this blog?
  • seriously, that's just happening (I am especially excited about CDI's portable extensions Gavin has been blogging about lately).
Bean Validation is voted YES!
11. Nov 2009, 09:48 CET, by Emmanuel Bernard

That's now official, the Bean Validation specification has been voted YES by the JCP expert committee. That's the culmination of two and a half years of work. (I know the vote has ended nov 2nd but nobody told me ;) )

Many many thanks to all the persons involved that believed in this spec, worked on it, provided feedback and improvements over time whether it be the members of the expert group, of other expert groups or people in the community. Bringing a specification to birth is very tough, I have a lot more respect for specification leads now ;)

The final specification should officially show up soon on the JSR-303 webpage but in the mean time, you can read it here.

Now go download Hibernate Validator 4 and use it. The next preview of JBoss AS (due very soon) will contain support for JSF 2, Bean Validation (via Hibernate Validator), Java Context and Dependency injection (via Weld) and partial support for JPA 2 (via Hibernate 3.5.Beta2). All these specs and products integrate with each other to provide cross-the-board validation.

Now off to my Bean Validation presentation at W-JAX.

PS: Congratulations to the 299 EG and to the WebBea-ahem Weld team for their release.

Hibernate Validator 4 unleashed
13. Oct 2009, 14:49 CET, by Emmanuel Bernard

After many months of polishing, we are happy to release Hibernate Validator 4. This is a major milestone for Hibernate Validator with tons of new features and a spec compliance.

For the newcomers

Hibernate Validator let's you declare constraints on your domain model using annotations like @NotNull or @Size and returns the list of constraint failures found in an object graph. Instead of duplicating constraint declarations in various application layers, constraints are centralized on your domain model and shared by all layers and frameworks: declared once, validate anywhere if you will.

What's new and cool?

Hibernate Validator is a complete rewrite and has many many many new features. Let me describe a handful of them:

  • constraint composition: a custom constraint can be composed of smaller constraints, avoiding code duplication, improving readability and increasing portability especially when combined with the set of built-in constraints.
  • groups: groups allow you to define a subset of the constraints you want to see validated at a given time. Useful in many situations like partially filled data, check the state of an object (can this user buy in one click?), order constraint validations. Oh and groups are not mere strings, they are a type-safe construct build on top of Java interfaces.
  • type-safe constraint declaration: Hibernate Validator 4 ensures that constraints set on a property are compatible with the property's type. This can even be theoretically checked at compile time.
  • more powerful custom constraints: as easy as before, more powerful than before. You can now customize the constraint violation messages reported by custom constraints and potentially return several violations if needed. A violation can point to a sub-property (useful for cross-property validations).
  • native integration with JPA 2 and JSF 2: Hibernate Validator 4 natively integrates with Java Persistence 2 and Java Server Faces 2 due to it's Bean Validation compliance. This integration is in the work in JBoss AS 5.2. People using Seam and Hibernate Core are already familiar with these style of integration since Hibernate Validator 3.
  • fluent type-safe bootstrap API: you can refine many aspects of Hibernate Validator like the message interpolation logic using the new bootstrap API.
  • metadata API: frameworks in need to query the constraints on a domain model can use the metadata API. This is for example used by Hibernate Core to propagate constraints to the database schema.
  • XML: XML configuration can be used in combination with or instead of annotations allowing for example redefinition of some constraints depending on the deployment environment.
  • a much improved test suite: we have completely rewritten the test suite which is now the base of the specification TCK.
  • compliance with JSR-303 Bean Validation: last but not least, Hibernate Validator 4 is the reference implementation, we couldn't make it more compliant ;) Practically, for you, it means you code against the specification API making your code more portable and your constraints will be visible by the whole Java ecosystem provided that they integrate Bean Validation (like Java EE 6 did for example).

Of course there are many other new features, check out the documentation here. You can download Hibernate Validator 4 from there and reach us in our forum.

The second good news is that the Bean Validation specification is now finished. I will hand it over to the JCP for final approval ballot today. More on that in a few days.

Many thanks to Hardy, the person behind Hibernate Validator 4's implementation for coping with last month/day/minute/second enhancements to the specification. A special thanks to Gunnar Morling and Alaa Nassef for their contribution despite a few administrative hiccups :)

Showing 1 to 5 of 50 blog entries