Red Hat

In Relation To

The Hibernate team blog on everything data.

Multitenancy and current session

Posted by Emmanuel Bernard    |    Jun 26, 2015    |    Tagged as Hibernate ORM

Today let’s discuss the interaction between multitenancy and the current session feature.

Multitenancy let’s you isolate Session operations between different tenants. This is useful to create a single application isolating different customers from one another.

The current session feature returns the same session for a given context, typically a (JTA) transaction. This facilitates the one session per view/transaction/conversation pattern and avoids the one session per operation anti-pattern.

Session session = sessionFactory.getCurrentSession();
// do some other work
[...]
// later in the same context (e.g. JTA Transaction)
Session session2 = sessionFactory.getCurrentSession();

// semantically we have
assert session == session2

The two features work well together, simply implement CurrentTenantIdentifierResolver. That will give Hibernate ORM the expected tenant id when the current session is created.

How current is current?

When discussing with Florian and the ToulouseJUG, we exchanged on a small case where things might not work as you expect. Hibernate ORM considers that, for a given context (e.g. transaction), there can only be a single current Session.

So if in the same context (e.g. transaction):

  • your CurrentTenantIdentifierResolver implementation returns different values of tenant id,

  • you use getCurrentSession()

you will get a TenantIdentifierMismatchException.

However, it is sometimes useful to be able to reach several tenants from the same context. You have two options:

  • Manually create the Session

  • Implement a custom CurrentSessionContext

Manually create the Session

You can use the SessionFactory API to create a Session for the tenant id you are looking for.

Session session1 = sessionFactory.withOptions()
        .tenantIdentifier( tenant1 )
        ...
        .openSession();
Session session2 = sessionFactory.withOptions()
        .tenantIdentifier( tenant2 )
        ...
        .openSession();

But you have to make sure to close these sessions. If you are used to CDI or Spring handling sessions for you, or if you rely on the current session feature to propagate the session across your stack, this might be annoying.

Implement a custom CurrentSessionContext

The alternative is to implement your own version of CurrentSessionContext, avoid raising the TenantIdentifierMismatchException, and keep Session instances per both context and tenant id.

In practice, current sessions are stored in a ConcurrentHashMap keyed by context identifier, you just need to improve that part. Start with JTASessionContext and hack away!

What now?

We are currently discussing whether the default CurrentSessionContext implementations should partition by tenant id or raise the exception. If you have your opinion, chime in!

In the mean time, use one of the options above.

When creating a bug report for any project within the Hibernate family, it’s extremely helpful (and, frankly, required) to have an adequate test case available. This is obviously important to make reproducing the issue as easy as possible. But it’s also vital longer-term. Nearly every bug fix should include a regression test, which is frequently based on the original reproducer (sometimes, it’s the reproducer, verbatim).

To help create useful test cases, we’re opening up a repo with various templates. Please see the READMEs in each project’s subdir for more info: Hibernate Test Case Templates

As a starting point, the repo contains two templates for ORM:

  • ORMUnitTestCase: By far, this one’s the most helpful. ORM includes a built-in unit test framework that does much of the heavy lifting for you. All that’s required is your entities, logic, and any necessary settings. Since we nearly always include a regression test with bug fixes, providing your reproducer using this method simplifies the process. We can then directly commit it, without having to mold it in first. What’s even better? Fork hibernate-orm itself, add your test case directly to a module’s unit tests (using the template class), then submit it as a PR!

  • ORMStandaloneTestCase: This template is standalone and will look familiar. It simply uses a run-of-the-mill ORM setup. Although it’s perfectly acceptable as a reproducer, lean towards ORMUnitTestCase whenever possible.

The eventual goal is to also include templates for Validator, Search, and OGM.

As always, this is open source for a reason! If the templates can be improved in any way, please let us know (either through our JIRA instance or through GitHub Issues). Better yet, send us a pull request!

Revamped blog

Posted by Emmanuel Bernard    |    Jun 25, 2015    |    Tagged as Discussions

Welcome to the newly revamped Hibernate and friends blog.

As you can see, we made it look like hibernate.org and we took the opportunity to clean up the tags to make them more useful. But we had other reasons to migrate.

Blog early, blog often

We have been very happy with the Asciidoctor-based writing experience of both our reference documentation and of hibernate.org. We are bringing this ease of writing to our blog and the not so secret objective is for us to blog more. So if you don’t see more content here, you can start yelling at us :)

Write once, display anywhere

There is an added bonus to using Asciidoctor for all of our writing: we can move content easily between systems. What starts as a blog can easily become a how-to page on the site or a section in the reference documentation.

Maintenance

We had a few issues with the old infrastructure that were keeping us away from our IDEs a bit too often for comfort.
This blog is a statically generated site, we use Awestruct. This means that we can make is scale very easily and with very low maintenance. Nothing beats plain old HTML :)

We did migrate all the old entries and comments from the old blog: fear not, nothing is lost.

If you seen any issue, let us know in the comments or by tweet. Oh and enlist to our new feed URL.

Hibernate Search 5.3.0.Final now available!

Posted by Sanne Grinovero    |    Jun 10, 2015    |    Tagged as Hibernate Search

As suggested last week, today we released Hibernate Search version 5.3.0.Final.

Compared to the previous candidate release, the only changes are some minor clarifications in the documentation.

   <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-search-orm</artifactId>
      <version>5.3.0.Final</version>
   </dependency>

Faceting API changes

The new great faceting integration comes at a small migration cost: remember you now need to use the new @Facet annotation as explained in the the example of the previous post.

What's next?

Barring some maintenance needs on this branch 5.3, we have no plans of other Hibernate Search releases to target Hibernate ORM 4.3.x. The focus is now on Hibernate 5 compatibility.

  • Artefact jars are available on Maven Central under the GAV org.hibernate:hibernate-search-orm:5.3.0.Final
  • Tarballs and zip bundles can be downloaded from our website
  • Feedback is welcome on the forums and emails, IRC

For those of you using Hibernate ORM version 5.0.0.CR1, you can now use the freshly released Hibernate Search 5.4 version 5.4.0.Alpha1.

What's new

Absolutely nothing! This Hibernate Search version is identical in terms of features and API to version 5.3.0.CR1: this should make it easier for you all to upgrade the Hibernate ORM libraries (hibernate-core, hibernate-entitymanager,..) without the distraction of changes because of Hibernate Search: focus on the changes you'll need to apply because of the major version upgrade of Hibernate (if any, as it's not too complex at all).

WildFly compatibility and JBoss Modules

With every release of Hibernate Search we normally also release a set of modules to run the latest version of it on WildFly, but in this case since the updated Hibernate ORM 5 integrations for WildFly have yet to be released, we skipped this step. Fear not, the WildFly integration will be finished soon and we'll then resume releasing such module packs as usual. Not least, this very same version of Hibernate Search will soon be available in WildFly 10, so the modules missing today won't actually be needed at all.

This is a great time to try Hibernate 5

While the latest polish is performed on Hibernate 5, we're all looking forward for feedback from you. It is likely that some more changes will be done, but we consider it good enough already to not expect any regression so please try it and let us know! We're at that sweet spot in which you can still propose changes without the chains of strong API compatibility requirements, but good enough for you to not be wasting time on a quickly changing target.

Versions reminder

This version of Hibernate Search requires:

  • Hibernate ORM 5.0.0.CR1
  • Apache Lucene 4.10.x
  • Java SE 7

Our rules and conventions for versions and compatibility are documented here on the GitHub Wiki.

  • Artefact jars are available on Maven Central under the GAV org.hibernate:hibernate-search-orm:5.4.0.Alpha1
  • Zip and tar bundles are available via our website
  • Feedback is welcome on the forums and emails, IRC

Welcome back to our tutorial series “NoSQL with Hibernate OGM”!

In this part you will learn how to use Hibernate OGM from within a Java EE application running on the WildFly server. Using the entity model you already know from the previous parts of this tutorial, we will build a small REST-based application for managing hikes. In case you haven’t read the first two installments of this series, you can find them here:

In the following you will learn how to prepare WildFly for using it with Hibernate OGM, configure a JPA persistence unit, create repository classes for accessing your data and providing REST resources on top of these. In this post we will primarily focus on the aspects related to persistence, so some basic experience with REST/JAX-RS may help. The complete source code of this tutorial is hosted on GitHub.

Preparing WildFly

The WildFly server runtime is based on the JBoss Modules system. This provides a modular class-loading environment where each library (such as Hibernate OGM) is its own module, declaring the list of other modules it depends on and only “seeing” classes from those other dependencies. This isolation provides an escape from the dreaded “classpath hell”.

ZIP files containing all the required modules for Hibernate OGM are provided on SourceForge. Hibernate OGM 4.2 - which we released yesterday - supports WildFly 9, so download hibernate-ogm-modules-wildfly9-4.2.0.Final.zip for that. If you are on WildFly 8, use Hibernate OGM 4.1 and get hibernate-ogm-modules-wildfly8-4.1.3.Final.zip instead.

Unzip the archive corresponding to your WildFly version into the modules directory of the application server. If you prefer that the original WildFly directories remain unchanged, you also can unzip the Hibernate OGM modules archive to any other folder and configure this as the “module path” to be used by the server. To do so, export the following two environment variables, matching your specific environment:

export JBOSS_HOME=/path/to/wildfly
export JBOSS_MODULEPATH=$JBOSS_HOME/modules:/path/to/ogm/modules

In case you are working with the Maven WildFly plug-in, e.g. to launch WildFly during development, you’d achieve the same with the following plug-in configuration in your POM file:

...
<plugin>
    <groupId>org.wildfly.plugins</groupId>
    <artifactId>wildfly-maven-plugin</artifactId>
    <version>1.1.0.Alpha1</version>
    <configuration>
        <jboss-home>/path/to/wildfly</jboss-home>
        <modules-path>/path/to/ogm/modules</modules-path>
    </configuration>
</plugin>
...

Setting up the project

Start by creating a new Maven project using the “war” packaging type. Add the following to your pom.xml:

...
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.hibernate.ogm</groupId>
            <artifactId>hibernate-ogm-bom</artifactId>
            <type>pom</type>
            <version>4.2.0.Final</version>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
...

This makes sure you get matching versions of Hibernate OGM’s modules and any (optional) dependencies. Then add the dependency to the Java EE 7 API and one of the Hibernate OGM backend modules, e.g. Infinispan, JBoss’ high-performance, distributed key/value data grid (any other such as hibernate-ogm-mongodb or the brand-new hibernate-ogm-cassandra module would work as well):

...
<dependencies>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate.ogm</groupId>
        <artifactId>hibernate-ogm-infinispan</artifactId>
        <scope>provided</scope>
    </dependency>
</dependencies>
...

The provided scope makes these dependencies available for compilation but prevents them from being added to the resulting WAR file. That it because the Java EE API is part of WildFly already, and Hibernate OGM will be contributed through the modules you unzipped before.

Just adding these modules to the server doesn’t cut it, though. They also need to be registered as a module dependency with the application. To do so, add the file src/main/webapp/WEB-INF/jboss-web.xml with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure
    xmlns="urn:jboss:deployment-structure:1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <deployment>
        <dependencies>
            <module name="org.hibernate" slot="ogm" services="import" />
            <module name="org.hibernate.ogm.infinispan" services="import" />
            <module name="org.hibernate.search.orm" services="import" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>

This will make Hibernate OGM core and the Infinispan backend as well as Hibernate Search available to your application. The latter will be used to run JP-QL queries in a bit.

Adding entity classes and repositories

With the basic project infrastructure in place, it’s time to add the entity classes and repository classes for accessing them. The entity types are basically the same as seen in part 1, only now they are annotated with @Indexed in order to allow them to be queried via Hibernate Search and Lucene:

@Entity
@Indexed
public class Person {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    private String firstName;
    private String lastName;

    @OneToMany(
        mappedBy = "organizer",
        cascade = { CascadeType.PERSIST, CascadeType.MERGE },
        fetch = FetchType.EAGER
    )
    private Set<Hike> organizedHikes = new HashSet<>();

    // constructors, getters and setters...
}
@Entity
@Indexed
public class Hike {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    private String description;
    private Date date;
    private BigDecimal difficulty;

    @ManyToOne
    private Person organizer;

    @ElementCollection(fetch = FetchType.EAGER)
    @OrderColumn(name = "sectionNo")
    private List<HikeSection> sections;

    // constructors, getters and setters...
}
@Embeddable
public class HikeSection {

    private String start;
    private String end;

    // constructors, getters and setters...
}

In order to use these entities, a JPA persistence unit must be defined. To do so, create the file src/main/resources/META-INF/persistence.xml:

<?xml version="1.0" encoding="utf-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">

    <persistence-unit name="hike-PU" transaction-type="JTA">
        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>

            <class>org.hibernate.ogm.demos.ogm101.part3.model.Person</class>
            <class>org.hibernate.ogm.demos.ogm101.part3.model.Hike</class>

            <properties>
                <property name="hibernate.ogm.datastore.provider" value="INFINISPAN" />
                <property name="hibernate.ogm.datastore.database" value="hike_db" />
                <property name="hibernate.ogm.datastore.create_database" value="true" />
            </properties>
    </persistence-unit>
</persistence>

Here we define a persistence unit named “hike-PU”. Infinispan is a fully transactional datastore, and using JTA as transaction type allows the persistence unit to participate in container-managed transactions. Specifying HibernateOgmPersistence as the provider class enables Hibernate OGM (instead of Hibernate ORM), which is configured with some properties for the setting backend (INFINISPAN in this case), database name etc.

Note that it actually should not be required to specify the entity types in persistence.xml when running in a Java EE container such as WildFly. Instead they should be picked up automatically. When using Hibernate OGM this unfortunately is needed at the moment. This a known limitation (see OGM-828) which we hope to fix soon.

The next step is to implement repository classes for accessing hike and organizer data. As an example, the following shows the PersonRepository class:

@ApplicationScoped
public class PersonRepository {

    @PersistenceContext
    private EntityManager entityManager;

    public Person create(Person person) {
        entityManager.persist( person );
        return person;
    }

    public Person get(String id) {
        return entityManager.find( Person.class, id );
    }

    public List<Person> getAll() {
        return entityManager.createQuery( "FROM Person p", Person.class ).getResultList();
    }

    public Person save(Person person) {
        return entityManager.merge( person );
    }

    public void remove(Person person) {
        entityManager.remove( person );
        for ( Hike hike : person.getOrganizedHikes() ) {
            hike.setOrganizer( null );
        }
    }
}

The implementation is straight-forward; by means of the @ApplicationScoped annotation, the class is marked as application-scoped CDI bean (i.e. one single instance of this bean exists throughout the lifecycle of the application). It obtains a JPA entity manager through dependency injection and uses the same to implement some simple CRUD methods (Create, Read, Update, Delete).

Note how the getAll() method uses a JP-QL query to return all person objects. Upon execution this query will be transformed into an equivalent Lucene index query which will be run through Hibernate Search.

The hike repository looks very similar, so it’s omitted here for the sake of brevity. You can find its source code on GitHub.

Exposing REST services

JAX-RS makes building REST-ful web services a breeze. It defines a declarative programming model where you annotate plain old Java classes to provide implementations for the GET, POST, PUT etc. operations of an HTTP endpoint.

Describing JAX-RS in depth is beyond the scope of this tutorial, e.g. refer to the Java EE 7 tutorial if you would like to learn more. Let’s just have a look at the some methods of a resource class for managing persons as an example:

@Path("/persons")
@Produces("application/json")
@Consumes("application/json")
@Stateless
public class Persons {

    @Inject
    private PersonRepository personRepository;

    @Inject
    private ResourceMapper mapper;

    @Inject
    private UriMapper uris;

    @POST
    @Path("/")
    public Response createPerson(PersonDocument request) {
        Person person = personRepository.create( mapper.toPerson( request ) );
        return Response.created( uris.toUri( person ) ).build();
    }

    @GET
    @Path("/{id}")
    public Response getPerson(@PathParam("id") String id) {
        Person person = personRepository.get( id );
        if ( person == null ) {
            return Response.status( Status.NOT_FOUND ).build();
        }
        else {
            return Response.ok( mapper.toPersonDocument( person ) ).build();
        }
    }

    @GET
    @Path("/")
    public Response listPersons() {  }

    @PUT
    @Path("/{id}")
    public Response updatePerson(PersonDocument request, @PathParam("id") String id) {  }

    @DELETE
    @Path("/{id}")
    public Response deletePerson(@PathParam("id") String id) {  }
}

The @Path, @Produces and @Consumes annotations are defined by JAX-RS. They bind the resource methods to specific URLs, expecting and creating JSON based messages. @GET, @POST, @PUT and @DELETE configure for which HTTP verb each method is responsible.

The @Stateless annotation defines this POJO as a stateless session bean. Dependencies such as the PersonRepository can be obtained via @Inject-based dependency injection. Implementing a session bean gives you the comfort of transparent transaction management by the container. Invocations of the methods of Persons will automatically be wrapped in a transaction, and all the interactions of Hibernate OGM with the datastore will participate in the same. This means that any changes you do to managed entities - e.g. by persisting a new person via PersonRepository#create() or by modifying a Person object retrieved from the entity manager - will be committed to the datastore after the method call returns.

Mapping models

Note that the methods of our REST service do not return and accept the managed entity types themselves, but rather specific transport structures such as PersonDocument:

public class PersonDocument {

    private String firstName;
    private String lastName;
    private Set<URI> organizedHikes;

    // constructors, getters and setters...
}

The reasoning for that is to represent the elements of associations (Person#organizedHikes, Hike#organizer) in form of URIs, which enables a client to fetch these linked resources as required. E.g. a GET call to http://myserver/ogm-demo-part3/hike-manager/persons/123 may return a JSON structure like the following:

{
    "firstName": "Saundra",
    "lastName": "Johnson",
    "organizedHikes": [
        "http://myserver/ogm-demo-part3/hike-manager/hikes/456",
        "http://myserver/ogm-demo-part3/hike-manager/hikes/789"
    ]
}

The mapping between the internal model (e.g. entity Person) and the external one (e.g. PersonDocument) can quickly become a tedious and boring task, so some tool-based support for this is desirable. Several tools exist for this job, most of which use reflection or runtime byte code generation for propagating state between different models.

Another approach for this is pursued by MapStruct, which is a spare time project of mine and generates bean mapper implementations at compile time (e.g. with Maven or in your IDE) via a Java annotation processor. The code it generates is type-safe, fast (it's using plain method calls, no reflection) and dependency-free. You just need to declare Java interfaces with mapping methods for the source and target types you need and MapStruct will generate an implementation as part of the compilation process:

@Mapper(
    // allows to obtain the mapper via @Inject
    componentModel = "cdi",

    // a hand-written mapper class for converting entities to URIs; invoked by the generated
    // toPersonDocument() implementation for mapping the organizedHikes property
    uses = UriMapper.class
)
public interface ResourceMapper {

    PersonDocument toPersonDocument(Person person);

    List<PersonDocument> toPersonDocuments(Iterable<Person> persons);

    @Mapping(target = "date", dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
    HikeDocument toHikeDocument(Hike hike);

    // other mapping methods ...
}

The generated implementation can then be used in the Persons REST resource to map from the internal to the external model and vice versa. If you would like to learn more about this approach for model mappings, check out the complete mapper interface on GitHub or the MapStruct reference documentation.

Wrap-up

In this part of our tutorial series you learned how to add Hibernate OGM to the WildFly application server and use it to access Infinispan as the data storage for a small REST application.

WildFly is a great runtime environment for applications using Hibernate OGM, as it provides most of the required building blocks out of the box (e.g. JPA/Hibernate ORM, JTA, transaction management etc.), tightly integrated and ready to use. Our module ZIP allows to put the Hibernate OGM modules into the mix very easily, without the need for re-deploying them each time with your application. With WildFly Swarm there is also support for the micro-services architectural style, but we’ll leave it for another time to show how to use Hibernate OGM with Wildfly Swarm (currently JPA support is still lacking from WildFly Swarm).

You can find the sources of the project on GitHub. To build the project run mvn clean install (which executes an integration test for the REST services using Arquillian, an exciting topic on its own). Alternatively, the Maven WildFly plug-in can be used to fire up a WildFly instance and deploy the application via mvn wildfly:run, which is great for manual testing e.g. by sending HTTP requests through curl or wget.

If you have any questions, let us know in the comments below or send us a Tweet to @Hibernate. Also your wishes for future parts of this tutorial are welcome. Stay tuned!

Tonight we released Hibernate Search version 5.3.0.CR1 (candidate release).

We consider this stable, and besides some pending documentation improvements, we'll re-publish the same implementation as 5.3.0.Final in ten days. Last chance to provide feedback! Please try it out.

Brand-new but proven faceting technology

The technology which Hibernate Search uses under the hood to implement this amazing feature has been improved and polished in various years by the Apache Lucene team. So far Hibernate Search has been using an old and proven technique but this had several limitations.

We believe the new implementation is now mature enough for our users too, and probably should have switched earlier if we didn't have other subjects to attack.

From a user's perspective, there are less limitations and the API is the same, with one migration catch: please remember you now need to opt-in the fields you want to use for faceting explicitly! For that, use the @Facet annotation as shown in the example of the previous post and in the Faceting reference documentation.

What's next?

Our immediate focus is to release am experimental tag to support Hibernate ORM 5: remember, Hibernate Search versions from 4.5 up to (and including) 5.3 are only compatible with Hibernate ORM versions 4.3.x.

Of course, we're also looking forward for feedback and will try and schedule any issues you encounter on the latest versions to be fixed ASAP. Suggestions and contributions are welcome as well!

  • Artefact jars are available on Maven Central under the GAV org.hibernate:hibernate-search-orm:5.3.0.CR1
  • Zip and tar bundles are available via our website
  • Feedback is welcome on the forums and emails, IRC

Hibernate OGM 4.2 Final is out

Posted by Davide D'Alto    |    Jun 2, 2015    |    Tagged as Hibernate OGM

After several months of hard work, I'm happy to announce the next final release of Hibernate OGM: 4.2.

What's new?

Compared to 4.1 Final, this version includes:

You can find more details for each one of them in our previous posts about release 4.2 Beta1 and 4.2 CR1.

A list of all resolved issues is available in the release notes (you can also find the one for 4.2.CR1 and the one for 4.2.Beta1).

How can I get it?

You can download Hibernate OGM 4.2.0.Final from SourceForge or via Maven, Gradle etc., using the following GAV coordinates:

  • org.hibernate.ogm:hibernate-ogm-core:4.2.0.Final for the Hibernate OGM engine and
  • org.hibernate.ogm:hibernate-ogm-<%DATASTORE%>:4.2.0.Final, depending on the backend you want to use.

I’m new to Hibernate OGM, where should I start?

If you are not familiar with Hibernate OGM, most of what you need is available in our web site. There is a getting started guide and the more complete reference documentation. And last but not least, for any help or feedback, reach us via our forum or via IRC.

What’s next?

We have plenty of ideas: migrate to Hibernate ORM 5, custom types, new datastores, denormalization engine, and more. You can influence what we are going to include in the next release letting us hear your voice with feedback, questions or ideas.

Many thanks to all the people that helped us make this release possible.

Hibernate ORM 5.0.0.CR1 Release

Posted by Steve Ebersole    |    May 28, 2015    |    Tagged as Hibernate ORM Releases

The Hibernate team is proud to announce the first candidate release for 5.0. The main changes since the Beta2 release include:

  • Initial generic typing for Hibernate native (Session, e.g.) APIs
  • Continued development of the new bytecode enhancement capabilities including improved support in the Maven and Gradle plugins
  • Support for parameterized types with AttributeConverter implementations
  • Improved OSGi integration testing using Pax Exam and Karaf, and publishing a hibernate-osgi Karaf features file
  • Auto quoting of keywords used as identifiers (User, e.g.).
  • Incorporating fixes, improvements and suggestions to the improved schema update and validation tooling

A lot of help from the community went into this release and the previous Beta releases. Thanks for all the help and work and testing and doggedness!

As always, see http://hibernate.org/orm/downloads/ for information on obtaining the releases.

Report any issues to Hibernate Jira

Moving along towards a 5.2 Final, we are happy to announce the release of Hibernate Validator 5.2.0.CR1. The main goal of this release was to fix bugs and polish some of the new features. For example, we reviewed the Optional validation support and made sure its behavior is (what we think) consistent in all cases. You can find the full change log on JIRA.

Despite the focus on bug fixes, we still managed to sneak in a couple of new features. Hibernate Validator offers now a TimeProvider contract, as well as an extension of the Path API which allows to obtain the value of the represented property. Refer to the online documentation for more information.

Another more general question, which created quite a bit of discussion, revolved around the validation of Java 8 date/time types (JSR 310) (see HV-874). The question is, whether we can/should provide default ConstraintValidator implementations for @Past and @Future validating LocalDate (or any of the other date/time types which do not represent a instant in time). The Javadocs tells us:

This class does not store or represent a time or time-zone. Instead, it is a description of the date, as used for birthdays. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.

Without a instant in time, however, past and future are undefined. One can only validate such an instant by associating a timezone with it. But which one? The time zone of the current JVM? That could lead to unexpected behavior for example in client-server applications. If you have an opinion on this or an idea on how to solve this, please leave a comment or use any of the other means listed below to get into touch with us. We would love to hear from you. For now, Hibernate Validator will not support LocalDate out of the box. We will see how this pans out.

Where do I get the release?

Maven artifacts can be found in the JBoss Maven repository (GAV org.hibernate:hibernate-validator:5.2.0.CR1) and will within a short time also be synced to Maven Central. Distribution bundles are as usual available on SourceForge.

Feedback and questions are welcome via the Hibernate Validator forum or on stackoverflow using the hibernate-validator tag.

Enjoy!

back to top