Hibernate, a Java-based Object/Relational (O/R) mapping framework, released version 3.3 today. InfoQ spoke with project lead Steve Ebersole to learn more about this release and what new capabilities it adds to Hibernate.
Major new features in Hibernate 3.3 include:
- Redesigned, modular JARs - There are now a number of fine-grained JARs rather than one large JAR - this allows users to more easily see and minimize their dependencies, and allows organizations to build customized Hibernate deployments with unwanted parts left out
- Maven-based build - Hibernate is now built using the Apache Maven build system
- Revamped caching SPI - Based on feedback, the cache system has been refactored to allow more fine-grained control of the characteristics of different cache regions
- JBoss Cache 2.x integration - Based upon the new caching SPI, JBoss Cache 2.x integration is now available out-of-the-box
Ebersole also explained in more detail the new cache system and the JBoss Cache integration:
The main SPI changes revolve around the ability to build cache regions intended for a particular purpose. Hibernate basically needs cache regions for 4 distinct purposes: entity data, collection data, query results, update-timestamps. The previous SPI tried to handle these different types in a singular manner; essentially it tried to treat caching of data in a ubiquitous way regardless of the characteristics of the data being stored. What we had found in practice, however, is that many times caching integrators need to account for those different characteristics. For example, with a clustered cache perhaps it makes sense to use synchronous invalidation for entity and collection data and a local-only mode for the query and update-timestamps regions. That kind of mix-and-match was not possible with the previous SPI without making some hacky assumptions based on the region names. The new SPI makes these distinctions explicit. So for example there is a method to "buildEntityRegion" or to "buildCollectionRegion" so that the caching integrator can know for sure the type of data that given region is expected to hold and build an appropriate configured cache/region.
The JBossCache 2.x integration is currently the only caching integration directly using this new SPI (the rest use a bridge between the new and old, now-deprecated SPI). As such, it takes full advantage of the distinction I mentioned above to allow users to define different behaviors for the various regions. With JBossCache 2.x, there are 2 specific improvements over JBossCache 1.x in terms of benefiting the Hibernate use-case. First is the addition of a "putForExternalRead" process. With JBossCache 1.x we would run into performance and sometimes even deadlock issues when reading data from the database and putting that into the JBossCache region. What happens is that JBossCache would acquire a write-lock on the node to which we were attempting to put the just-read data even though the semantics of the overall use-case would warrant a read-lock. That write-lock would then block other transactions. JBossCache 2.x introduces a method specifically designed for this use-case of which the integration takes advantage.
The other significant improvement in JBossCache 2.x from the perspective of Hibernate usage is the fact that it does a better job managing cluster-wide invalidation, particularly with optimistic locking. The biggest change there is ensuring a "tombstone" is left around for an invalidated entity so any subsequent attempt to write that entity in the cache knows what the invalidated version was and a proper version check can be performed. Invalidation is important in regards to Hibernate as it's the most performant way to run a clustered entity cache.
Another area which was discussed was how Hibernate has been affected by other JPA implementations:
At the time was I first looking at TopLink/OpenJPA I also happened to be doing some work with the BytecodeProvider support in Hibernate. I really liked the idea of using JVM agents for dynamically instrumenting classes as they are loaded rather than requiring a separate build-time step. That has not yet made its way into Hibernate, but I plan on looking at that with Hibernate 4.0 since it will drop support for JDK 1.4.
With the increase in popularity of OSGi recently, one issue which has been raised is the problems which sometimes occur when running Hibernate inside of an OSGi container. Ebersole said that the ability to dynamically redefine a SessionFactory is currently being looked at, and that the classloading issues are now also known to them. However, Ebersole noted that no hibernate-dev emails and only a few JIRA issues had discussed either of these issues, and that to the best of his knowledge nobody on the Hibernate development team had ever been approached about these issues. Ebersole expressed a strong desire to work together with the community to solve these and any other issues which arise with Hibernate, and also said that if someone with OSGi interest or knowledge wanted to help Hibernate to have better OSGi interoperability, or even just to scope out what such a compatibility effort would entail, that he would be interested in hearing from them.
When asked about future plans for Hibernate, Ebersole said:
Now that 3.3.0 GA has been released, we will have a period of concerted cleanup of outstanding issues in JIRA for 3.3.x.
We are already working on plans for both 3.4 and 4.0. Generally speaking we don't really discuss future roadmaps, but since work on 3.4 has begun and its feature-set is largely determined already I feel comfortable discussing that a bit. A big focus there is improvements in performance and resource utilization with regards to using Hibernate in clustered fail-over scenarios. Another is the introduction of "fetch profiles" where you can set up named fetching strategies in your metadata and then enable those profiles dynamically on a Session at runtime. Those are the big ones for 3.4 anyway.