Red Hat

In Relation To

The Hibernate team blog on everything data.

Just a quick heads-up to French-speaking developers: I will be presenting the Elasticsearch integration in Hibernate Search at the Strasbourg Java User Group (ElsassJUG) meetup, at 7 PM on Wednesday 26th of April.

I will briefly introduce full-text search (why and how it’s done), then present how to use Hibernate Search to keep Lucene indexes in sync with your Hibernate ORM entities, and I will show you how easy it is to target Elasticsearch instead of local Lucene indexes since Hibernate Search 5.6.0.

For more information about the location or to register, please refer to the Meetup page.

Hibernate Community Newsletter 8/2017

Posted by    |       |    Tagged as Discussions Hibernate ORM

Welcome to the Hibernate community newsletter in which we share blog posts, forum, and StackOverflow questions that are especially relevant to our users.

Articles

The Hibernate ResultTransformer is extremely useful to customize the way you fetch data from the database. Check out this article to learn more about this topic.

JPA and Hibernate use the first-level cache as a staging buffer for every read/write operation, and understanding its inner workings is very important if you want to use JPA effectively. For more details, you should definitely read this article.

Marco Behler offers 6 very practical video tutorials for Hibernate beginners.

Dealing with difficult software problems is easier than you might think. Check out this article for more details on how you can solve any software issue with the help of our wonderful software community.

If you wonder why you should choose Hibernate over plain JDBC, this article gives you 15 reasons why Hibernate is worth using.

This very short article offers a quick introduction to mapping a bidirectional one-to-many association. If you want to know what is the best way to map a one-to-many database relationship, then you should definitely read this article as well.

Database concurrency control is a very complex topic. PostgreSQL advisory locks are a very useful concurrency control API which you can use to implement multi-node coordination mechanisms. Check out this article for more details on this topic.

Time to upgrade

Hibernate ORM 5.2.10 has been released, as well as Hibernate Search 5.8.0.Beta1 which is now compatible with ElasticSearch 5.

We just published Hibernate Search version 5.8.0.Beta1, which is now compatible with Elasticsearch versions 5.x.

New improved Elasticsearch client

This release now uses the new Elasticsearch REST client, which is expected to be a safe choice in terms of long term maintenance as it’s sponsored and recommended by the Elasticsearch team.

Compared to the driver we used previously, this one uses a state of the art reactive architecture, so we can take advantage of more efficient resource utilization.

Elasticsearch 2.x is still supported

The new driver is backwards compatible, so we’ll still be able to connect to clusters running Elasticsearch 2.x.

This doesn’t need any configuration flag as Hibernate Search can automatically detect the version of Elasticsearch it’s being pointed to.

The features supported by Elasticsearch 5.x and 2.x are however slightly different and you’ll find that some low level mapping features are documented as compatible with only one specific version.

The migration guide will be updated when this minor release will be feature complete.

New Simple Query String supported by the Query builder DSL

The useful capabilities from Lucene’s SimpleQueryParser are now conveniently exposed by our higher level DSL.

We’ll publish a detailed blog about this new feature soon: stay tuned!

If you can’t wait, we won’t prevent you from peeking into the Simple Query String documentation.

Simplified JNDI configuration

If you integrated any external component into Hibernate Search using JNDI, for example a JMS queue or an Infinispan cache, this configuration was simplified.

You will no longer need to set Hibernate Search specific configuration properties such as how to set the InitialContext for JNDI lookups: only configure Hibernate ORM, and Hibernate Search will inherit the same settings.

How to get these releases

All versions are available on Hibernate Search’s web site.

Ideally use a tool to fetch it from Maven central; these are the coordinates:

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-search-orm</artifactId>
   <version>5.8.0.Beta1</version>
</dependency>

To use the experimental Elasticsearch integration you’ll also need:

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-search-elasticsearch</artifactId>
   <version>5.8.0.Beta1</version>
</dependency>

Downloads from Sourceforge are available as well.

Feedback

Feedback always welcome!

Please let us know of any problem or suggestion by creating an issue on JIRA, or by sending an email to the developer’s developer’s mailing lists, or posting on the forums.

We also monitor Stack Overflow; when posting on SO please use the tag hibernate-search.

Tenth bug-fix release for ORM 5.2

Posted by    |       |    Tagged as Hibernate ORM Releases

The Tenth bug-fix release for Hibernate ORM 5.2 has just been published. It is tagged at https://github.com/hibernate/hibernate-orm/releases/tag/5.2.10

The complete list of changes can be found here (or here for people without a Hibernate Jira account).

For information on consuming the release via your favorite dependency-management-capable build tool, see http://hibernate.org/orm/downloads/

The release bundles can be obtained from SourceForge or BinTray.

Accessing private state of Java 9 modules

Posted by    |       |    Tagged as Discussions

Data-centric libraries often need to access private state of classes provided by the library user.

An example is Hibernate ORM. When the @Id annotation is given on a field of an entity, Hibernate will by default directly access fields - as opposed to calling property getters and setters - to read and write the entity’s state.

Usually, such fields are private. Accessing them from outside code has never been a problem, though. The Java reflection API allows to make private members accessible and access them subsequently from other classes. With the advent of the module system in Java 9, rules for this will change a bit, though.

In the following we’ll explore the options authors of a library provided as a Java 9 module have to access private state of classes defined in other modules.

An example

As an example, let’s consider a simple method which takes an object - e.g. an instance of an entity type defined by the user - and a field name and returns the value of the object’s field of that name. Using reflection, this method could be implemented like this (for the sake of simplicity, we are ignoring the fact that a security manager could be present):

package com.example.library;

public class FieldValueAccessor {

    public Object getFieldValue(Object object, String fieldName) {
        try {
            Class<?> clazz = object.getClass();
            Field field = clazz.getDeclaredField( fieldName );
            field.setAccessible( true );
            return field.get( object );
        }
        catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            throw new RuntimeException( e );
        }
    }
}

By calling Field#setAccessible() we can obtain the field’s value in the following, even if it had been declared private. The module descriptor for the library module is trivial, it just exports the package of the accessor class:

module com.example.library {
    exports com.example.library;
}

In a second module, representing our application, let’s define a simple "entity":

package com.example.entities;

public class MyEntity {

    private String name;

    public MyEntity(String name) {
        this.name = name;
    }

    // ...
}

And also a simple main method which makes use of the accessor to read a field from the entity:

package com.example.entities;

public class Main {
    public static void main(String... args) {
        FieldValueAccessor accessor = new FieldValueAccessor();
        Object fieldValue = accessor.getFieldValue( new MyEntity( "hey there" ), "name" );
        assert "hey there".equals( fieldValue );
    }
}

As this module uses the library module, we need to declare that dependency in the entity module’s descriptor:

module com.example.myapp {
    requires com.example.library;
}

With the example classes in place, let’s run the code and see what happens. It would have been fine on Java 8, but as of Java 9 we’ll see this exception instead:

java.lang.reflect.InaccessibleObjectException:
Unable to make field private final java.lang.String com.example.entities.MyEntity.name accessible:
module com.example.myapp does not "opens com.example.entities" to module com.example.library

The call to setAccessible() fails, as by default code in one module isn’t allowed to perform so-called "deep reflection" on code in another (named) module.

Open this module!

Now what can be done to overcome this issue? The error message is giving us the right hint already: the package with the type to reflect on must be opened to the module containing the code invoking setAccessible().

If a package has been opened to another module, that module can access the package’s types reflectively at runtime. Note that opening a package will not make it accessible to other modules at compile time; this would require the package to be exported instead (as in the case of the library module above).

There are several options for opening a package. The first is to make the module an open module:

open module com.example.myapp {
    requires com.example.library;
}

This opens up all packages in this module for reflection by all other modules (i.e. this would be the behavior as known from other module systems such as OSGi). In case you’d like some more fine-grained control, you can opt to open specific packages only:

module com.example.myapp {
    opens com.example.entities;
    requires com.example.library;
}

This will allow for deep reflection on the entities package, but not on other packages within the application module. Finally, there is the possibility to limit an opens clause to one or more specific target modules:

module com.example.myapp {
    opens com.example.entities to com.example.library;
    requires com.example.library;
}

That way the library module is allowed to perform deep reflection, but not any other module.

No matter which of these options we use, the library module can now make private fields of types in the entities package of the entities module accessible and subsequently read or write their value.

Opening up packages in one way or another lets library code written prior to Java 9 continue to function as before. It requires some implicit knowledge, though. I.e. application developers need to know which libraries need reflective access to which types so they can open up the right packages. This can become tough to manage in more complex applications with multiple libraries performing reflection.

Luckily, there’s a more explicit approach in the form of variable handles.

Can you handle the var?

Variable handles - defined by JEP 193 - are a very powerful addition to the Java 9 API, providing "read and write access to [variables] under a variety of access modes". Describing them in detail would go far beyond the scope of this post (refer to the JEP and this article if you would like to learn more). For our purposes let’s focus on their capability for accessing fields, representing an alternative to the traditional reflection-based approach.

So how could our FieldValueAccessor class be implemented using variable handles?

Var handles are obtained via the MethodHandles.Lookup class. If such lookup has "private access" to the entities module, it will let us access private fields of that module’s types. To get hold of such lookup, we let the client code pass in a lookup when bootstrapping the library code:

Lookup lookup = MethodHandles.lookup();
FieldValueAccessor accessor = new FieldValueAccessor( lookup );

In FieldValueAccessor#getFieldValue() we can now use the method MethodHandles#privateLookupIn() which will return a new lookup granting private access to the given entity instance. From that lookup we can eventually obtain a VarHandle which allows us to get the object’s field value:

public class FieldValueAccessor {

    private final Lookup lookup;

    public FieldValueAccessor(Lookup lookup) {
        this.lookup = lookup;
    }

    public Object getFieldValue(Object object, String fieldName) {
        try {
            Class<?> clazz = object.getClass();
            Field field = clazz.getDeclaredField( fieldName );

            MethodHandles.Lookup privateLookup = MethodHandles.privateLookupIn( clazz, lookup );
            VarHandle handle = privateLookup.unreflectVarHandle( field );

            return handle.get( object );
        }
        catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException( e );
        }
    }
}

Note that this only works if the original lookup has been created by code in the entities module.

This is because MethodHandles#lookup() is a caller sensitive method, i.e. the returned value will depend on the direct caller of that method. privateLookupIn() checks whether the given lookup is allowed to perform deep reflection on the given class. Thus a lookup obtained in the entities module will do the trick, whereas a lookup retrieved in the library module wouldn’t be of any use.

Which route to take?

Both discussed approaches let libraries access private state from Java 9 modules.

The var handle approach makes the requirements of the library module more explicit, which I like. Expecting a lookup instance during bootstrap should be less error-prone than the rather implicit requirement for opening up packages or modules.

Mails by the OpenJDK team also seem to suggest that - together with their siblings, method handles - var handles are the way to go in the long term. Of course it requires the application module to be cooperative and pass the required lookup. It remains to be seen how this could look like in container / app server scenarios, where libraries typically aren’t bootstrapped by the application code but by the server runtime. Injecting some helper code for obtaining the lookup object upon deployment may be one possible solution.

As var handles only are introduced in Java 9 you might want to refrain from using them if your library is supposed to run with older Java versions, too (actually, you can do both by building multi-release JARs). A very similar approach can be implemented in earlier Java versions using method handles (see MethodHandles.Lookup#findGetter()). Unfortunately, though, there’s no official way to obtain method handles with private access prior to Java 9 and the introduction of privateLookupIn​(). Ironically, the only way to get such handles is employing some reflection.

The final thing to note is that there may be a performance advantage to using var and method handles, as access checking is done only once when getting them (as opposed to every invocation). Some proper benchmarking would be in order, though, to see what’s the difference in a given use case.

As always, your feedback is very welcome. Which approach do you prefer? Or perhaps you’ve found yet other solution we’ve missed so far? Let us know in the comments below.

As the Bean Validation 2.0 spec is making good progress, you may want to try out the features of the new spec revision with your existing Java EE applications.

WildFly, as a compatible Java EE 7 implementation, comes with Bean Validation 1.1 and its reference implementation Hibernate Validator 5 out of the box. In the following we’ll show you how easy it is to upgrade the server’s modules to the latest Bean Validation release, using a patch file provided by Hibernate Validator.

Getting the patch files

First download the patch file of the Hibernate Validator version you want to upgrade to. The latest release of Hibernate Validator at this point is 6.0.0.Alpha2 which implements the 2.0.0.Alpha2 release of Bean Validation. You can simply fetch the patch file for this release from Maven Central. If you are interested in the latest 5.x release of Hibernate Validator - which is the current stable implementation of Bean Validation 1.1 - you’d grab this file instead.

Both patches can be applied to WildFly 10.1 instances. Generally, we provide patch files for the latest stable version of WildFly at the time of the Hibernate Validator release.

Applying and undoing the patch

Once you’ve downloaded the patch file, change to the installation directory of your WildFly instance and run the following command to apply the patch:

./bin/jboss-cli.sh --command="patch apply hibernate-validator-modules-6.0.0.Alpha2-wildfly-10.1.0.Final-patch.zip"

Now (re-)start WildFly and you can begin to experiment with the new features of Hibernate Validator 6 and Bean Validation 2.0, such as the validation of container elements (think List<@Email String> emails), support for the Java 8 date/time API or the new built-in constraints such as @NotEmpty or @Email.

The nice thing of the patch mechanism is that patches aren’t actually modifying the patched WildFly instance. Any modules contained in the patch are just added in a separate "overlays" directory.

So in case you want go back to the version of Hibernate Validator originally coming with the server, just run this command to undo the patch:

./bin/jboss-cli.sh --command="patch rollback --reset-configuration=true"

You can learn more about the WildFly patching infrastructure in general here and here.

Bonus: Fully automated update for integration tests

In case you are running integration tests for your applications using the fabulous Arquillian framework, you can add the following configuration to your pom.xml. This will first download and extract WildFly, then download the patch file and apply it to the unzipped server:

...
<properties>
    <wildfly.version>10.1.0.Final</wildfly.version>
    <wildfly.core.version>1.0.1.Final</wildfly.core.version>
    <hibernate.validator.version>6.0.0.Alpha2</hibernate.validator.version>
</properties>
...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <id>unpack-wildfly</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>unpack</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>org.wildfly</groupId>
                                <artifactId>wildfly-dist</artifactId>
                                <version>${wildfly.version}</version>
                                <type>tar.gz</type>
                                <overWrite>false</overWrite>
                                <outputDirectory>${project.build.directory}</outputDirectory>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
                <execution>
                    <id>copy-patch</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>org.hibernate.validator</groupId>
                                <artifactId>hibernate-validator-modules</artifactId>
                                <version>${hibernate.validator.version}</version>
                                <classifier>wildfly-${wildfly.version}-patch</classifier>
                                <type>zip</type>
                                <outputDirectory>${project.build.directory}</outputDirectory>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.wildfly.plugins</groupId>
            <artifactId>wildfly-maven-plugin</artifactId>
            <version>1.1.0.Final</version>
            <dependencies>
                <!-- Contains the patch command -->
                <dependency>
                    <groupId>org.wildfly.core</groupId>
                    <artifactId>wildfly-patching</artifactId>
                    <version>${wildfly.core.version}</version>
                </dependency>
            </dependencies>
            <executions>
                <!-- Currently the WF Maven plug-in cannot apply offline commands,
                     although patch itself wouldn't require a running server;
                     see https://issues.jboss.org/projects/WFMP/issues/WFMP-11 -->
                <execution>
                    <id>start-wildfly-for-patching</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>start</goal>
                    </goals>
                </execution>
                <execution>
                    <id>apply-patch-file</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>execute-commands</goal>
                    </goals>
                    <configuration>
                        <fail-on-error>false</fail-on-error>
                        <commands>
                            <command>patch apply --path ${project.build.directory}/hibernate-validator-modules-${hibernate.validator.version}-wildfly-${wildfly.version}-patch.zip</command>
                        </commands>
                    </configuration>
                </execution>
                <execution>
                    <id>shutdown-wildfly-for-patching</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>shutdown</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <jbossHome>${project.build.directory}/wildfly-${wildfly.version}/</jbossHome>
            </configuration>
        </plugin>
    </plugins>
</build>
...

Applying this configuration will give you a WildFly instance with the latest release of Bean Validation and Hibernate Validator which you then can use as a deployment target for your integration tests, employing the latest Bean Validation 2.0 features. You can find a complete Maven project with a simple Arquillian test on GitHub in the hibernate-demos repository.

As you see it’s not difficult to upgrade WildFly 10 to Bean Validation 2.0, so don’t hesitate and give it a try. Your feedback on the new spec revision is always welcome on the mailing list or in the forum.

Hibernate Community Newsletter 7/2017

Posted by    |       |    Tagged as Discussions Hibernate ORM

Welcome to the Hibernate community newsletter in which we share blog posts, forum, and StackOverflow questions that are especially relevant to our users.

Upcoming events

Java Gruppen Danemark is hosting a High-Performance Hibernate webinar. If you want to participate, then you should register on Eventbrite.

Hibernate OGM will be at Devoxx UK 2017. If you want to learn more about Hibernate OGM and Infinispan, then you should definitely come to see Sanne’s presentation.

Articles

A very handy feature when working with JDBC batch updates is to find out which statement triggered a batch failure. Read this article for more info on this topic.

You can use Hibernate with CockroachDB. Check out this tutorial to see how easily you can integrate them.

Mapping the @OneToMany association is not as easy as you might think. Check out this article which shows you the best way to map a @OneToMany relationship.

Alon Segal shows you how to implement Multitenancy with Spring and Hibernate. Multitenancy is very handy when you need to support multiple customers on a single platform so that each customer is limited to its own tenant.

I read this article which describes a way to provide a JPA AttributeConverter to support Java 1.8 Data/Time types. However, this is not needed since Hibernate has been supported them for quite a while now.

For our Czech readers, Roman Pichlík wrote a very good article about all sorts of application performance issues, and the Open-Session in View is mentioned as well.

For our French readers, eXo platform has written an article that shows you how to integrate eXO with JPA and Hibernate.

Time to upgrade

Hibernate Validator 5.4.1 and 6.0.0 Alpha 2 are out.

GORM 6.1 has been released with support for Hibernate 5.2.

I’m honoured to confirm that I’ll be at Devoxx UK this May in London.

Come along in Gallery Hall at 12:55 on Thursday 11th of May to see a quick demo of Hibernate OGM used to migrate a JPA application from using a relational database to using a fast, scalable and highly available in memory data grid.

We announced support for storing data in Infinispan over the Hot Rod protocol in Hibernate OGM version 5.1, now is your chance to see it in action.

My slot is a "tools in action" and we’ll get straight to the point: find all details here.

Devoxx UK 2017 speaker button - Sanne Grinovero

New foray into serverless - announcing library shift

Posted by    |       |    Tagged as Discussions

Red Hat has been exploring serverless (aka FaaS) through the Fabric8 Funktion project. It has been long due for us to get serious on the subject. We are turning all of our libraries into services starting today. This is going to be a multi year effort but we are committed to it.

We thought hard and long about which service to start with. In our performance lab, we realized that the slowest and most expensive part of serverless functions was CPU branch misprediction. In a serverless approach, you want to squeeze as much operations per CPU cycle as possible. Any misprediction has huge consequences and kill any of the mechanical sympathy effort we put in libraries like vert.x.

In our experiments, we found that the optimal solution was to get rid of if branches in serverless functions. We are proud to introduce IF as a Service or IFaaS (pronounced aye face). Your code changes from:

user = retrieveUserProfile();
if ( user.isCustomer() ) {
    displayAds();
}
user.extractRevenu();

to

user = retrieveUserProfile();
if ( user.isCustomer(), "displayAdFunction" );
user.extractRevenu();

We have been using it for a year now and forked the javac compiler to convert each if branch into a proper if service call. But we also completely re shaped how we write code to pure linear code, changing all if primitives with their service call equivalent. This is great because it also fixed the tab vs space problem: we no longer have any indenting in our code. Two stones in one bird ! I cannot emphasize enough how much development speed we gained in our team by fighting less on each pull request against these tab bastards.

The good thing about this external if service is that you can add a sidecar proxy to cache and simulate branch predictions on OpenShift and scale then horizontally ad nauseam. This is a huge benefit compared to the hardcoded and embedded system that is a CPU. We typically change the branch implementation 3 to 5 times a day depending on user needs.

FAQ

Is else a function too?

Else is not part of the MVP but we have it working in the labs. We are currently struggling to implement for loops, more specifically nested ones. We have HTTP error 310: too many redirects errors.

Where can I download it ?

You can’t, it’s a service dummy. Go to <ifaas.io>.

Can I use it in Go?

Goggle did not accept our pull request. We have a fork called NoGo.

What is the pricing model?

The basic if service is and will remain free. We are working on added values with pro and enterprise plans.

Hibernate Validator 6 is going to be the Reference Implementation of Bean Validation 2.0. This Alpha2 release is coordinated with the 2.0.0.Alpha2 release of the Bean Validation specification.

It is also a playground used to validate future enhancements of the Bean Validation specification so feedback on the subjects presented here is very welcome!

Note that Hibernate Validator 6 requires JDK 8 or above.

If you missed the Alpha1 release, consulting its announcement might be beneficial to you before continuing your reading.

What’s new since Alpha1

Improved container element validation support

Container element validation support is the big new feature of Bean Validation 2.0 and it got some more love during this cycle.

Programmatic API and XML support

To obtain the equivalent of:

public class FishTank {

    private Optional<@Valid FishTankModel> model;

    private Map<@Size(min = 3, max = 10) String, @Min(1) Integer> fishCountByType;
}

it is now possible to declare container element type constraints and cascaded validation either via an XML mapping configuration (which is part of the Bean Validation 2.0 specification):

[...]
    <bean class="com.acme.FishTank" ignore-annotations="false">
        <field name="model">
            <containerElementType>
                <valid />
            </containerElementType>
        </field>
        <field name="fishCountByType">
            <containerElementType typeArgumentIndex="0">
                <constraint annotation="javax.validation.constraints.Size">
                    <element name="min">
                        <value>3</value>
                    </element>
                    <element name="max">
                        <value>10</value>
                    </element>
                </constraint>
            </containerElementType>
            <containerElementType typeArgumentIndex="1">
                <constraint annotation="javax.validation.constraints.Min">
                    <element name="value">
                        <value>1</value>
                    </element>
                </constraint>
            </containerElementType>
        </field>
    </bean>
[...]

or via the (implementation specific) programmatic API:

ConstraintMapping newMapping = config.createConstraintMapping();
newMapping
    .type( FishTank.class )
        .property( "model", FIELD )
            .containerElementType()
                .valid()
        .property( "fishCountByType", FIELD )
            .containerElementType( 0 )
                .constraint( new SizeDef().min( 3 ).max( 10 ) )
            .containerElementType( 1 )
                .constraint( new MinDef().value( 1 ) );

Other improvements

We also made a couple of more minor improvements:

  • the TYPE_ARGUMENT node type has been renamed to CONTAINER_ELEMENT (type argument don’t make sense for annotated array elements)

  • we allow per context custom value extractors

  • we allow value extractors to be contributed using the service loader mechanism

  • we allow to specify value extractors using XML configuration

  • we explore the parent classes and interfaces to search the ValueExtractor definition

Support for the new constraints added to Bean Validation 2.0

In the Alpha2 release of Bean Validation 2.0, we introduced the following new constraints:

  • @NotBlank: check that a char sequence is not blank (i.e. not null, and length of trimmed char sequence > 0)

  • @NotEmpty: check that an element (char sequence, collection, array) is not null and not empty

  • @Email: check that a char sequence is a valid email

  • @Positive: check that a number is positive

  • @Negative: check that a number is negative

We added support for these new constraints to Hibernate Validator.

Performance improvements

We started to run a few benchmarks on Hibernate Validator 6 and we fixed a few performance regressions.

6.0.0.Alpha2 is now significantly faster than 5.4, mostly thanks to the new ValueExtractor design.

Getting 6.0.0.Alpha2

To get the release with Maven, Gradle etc. use the GAV coordinates org.hibernate.validator:{hibernate-validator|hibernate-validator-cdi|hibernate-validator-annotation-processor}:6.0.0.Alpha2. Note that the group id has changed from org.hibernate (Hibernate Validator 5 and earlier) to org.hibernate.validator (from Hibernate Validator 6 onwards).

Alternatively, a distribution bundle containing all the bits is provided on SourceForge (TAR.GZ, ZIP).

Feedback, issues, ideas?

To get in touch, use the usual channels:

What’s next?

Bean Validation 2.0 and Hibernate Validator 6 are still under active development. We will release new alphas on a regular basis.

back to top