Help

I'm member of the Hibernate Team at Red Hat, currently working on Hibernate Validator, the reference implementation of JSR 349 (Bean Validation). I'm also serving in the JSR 349 expert group.

Location: Hamburg, Germany
Occupation: Hibernate team member
Archive

It’s my great pleasure to announce the release of Hibernate OGM 4.1.0.Beta7! The release brings support for MongoDB’s object id, a clarification of what are our public API/SPI packages as well as several bugfixes and many other improvements.

Use the following GAV coordinates with tools such as Maven, Gradle etc.:

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

Alternatively, there is a release bundle containing Hibernate OGM and all its dependencies available for download from SourceForge.

Support for MongoDB’s object id

When talking about Hibernate OGM, one of the most requested features we heard was support for the native object id type in MongoDB. Finally we got around to implementing this feature.

You can map object ids either directly via MongoDB’s org.bson.types.ObjectId type or using a String. The following shows an example:

@Entity
public class GolfPlayer {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Type(type = "objectid")
	private String id;

	// Alternatively, the following could be used:
	// @Id
	// @GeneratedValue(strategy = GenerationType.IDENTITY)
	// private ObjectId id;

	private String name;

	private double handicap;

	//...
}

The @GeneratedValue annotation causes the id to be automatically generated by MongoDB upon insertion of the entity, similar to e.g. AUTO_INCREMENT columns in MySQL. The @Type annotation makes sure the string is mapped as an object id rather than as plain string. So a GolfPlayer document could e.g. look like this:

{
    "_id" : ObjectId("542ac33630043ffe5bcb4efa"),
    "name" : "Alexis",
    "handicap" : 9.7
}

Also related to MongoDB is a nice improvement around JP-QL queries. You can now refer to properties of embeddable objects in your queries:

@Entity
@NamedQuery(name = “PersonsByCity”, query = "FROM Person p WHERE p.address.city = :pCity")
public class Person {

	@Id
	private ObjectId id;

	@Embedded
	private Address address;

	// ...
}

Here, the named query refers to the city property of the embedded address object.

API/SPI package restructuring

As we’re on our road to the 4.1.0.Final release, we spent a fair amount of time for clearly separating the OGM code base into API, SPI and internal packages. Our goal is to make clear what is supported in the long term and what is not.

API packages (application programming interface) are all those packages which are intended to be accessed by users of Hibernate OGM, i.e. people building applications on top of it. Any package which does not have “spi” or “impl” in its name is an API package. Note that there are only very few API packages in Hibernate OGM. Most of the time you will work with the JPA (javax.persistence.* packages) or the “classic” API from Hibernate ORM.

SPI packages (service provider interface) are packages which contain contracts to be used and/or implemented by authors of custom grid dialects. So if for instance you would write a dialect for your favorite NoSQL store (btw. you should consider to contribute it to OGM), then you would access the SPI packages. They have a “spi” in their name. In order to clearly separate API and SPI, we had to rename several packages and move some types around. So existing custom dialects need to be adapted to this new structure. Good news is that it basically is enough to do a “re-organize imports” in your favorite IDE to adapt to most of the changes. We aim at a stable SPI (and of course API as well) with the 4.1 Final release.

Finally, there are internal packages of the Hibernate OGM engine which are not intended for usage by users nor dialect implementors. You can recognize those by the “impl” in their name. Internal packages and types may be changed, removed etc. without notice. So if you think there is a specific internal type which you need to access, please let us know so we can decide what to do and e.g. promote it to API or SPI.

Please refer to the migration notes to learn more about the package changes in this release.

Useful links

As always we’re very interested in your feedback. Here are some helpful links for you:

So give it a try and let us know how you like this release!

The Hibernate team is very happy to announce the release of another Beta of Hibernate OGM 4.1!

Progress has been made with respect to query execution and the Neo4j dialect. Also we do provide a so-called Bill of Materials POM now which the Maven users out there will appreciate (details below).

The GAV coordinates to be used with Maven, Gradle etc. are:

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

Alternatively you can fetch a release bundle containing Hibernate OGM and all its dependencies from SourceForge.

Please note that this new release requires Hibernate ORM 4.3.6.Final or later.

Query improvements

We've reworked major parts of the integration with the query execution machinery from ORM. This enables quite a few improvements in the field of JP-QL as well as native queries.

One is support for polymorphic queries also on those backends which don't use Hibernate Search for querying (Neo4j and MongoDB). This means queries targetting a super-class will return instances of any mapped sub-class as well.

Furthermore, Hibernate OGM now shows the same behavior with respect to auto-flushing you already know from Hibernate ORM. That is, if you submit a query, all pending changes to entities of the effected types will be flushed to the data store in order to ensure queries don't return any stale data. Whereas this works nicely on stores supporting full transaction semantics (namely, Neo4j), some care must be taken on stores with limited or non-existing rollback capabilities. Refer to the reference guide to learn more about the details.

In addition we took measures to cache native queries derived from JP-QL queries. Note that this requires Hibernate ORM 4.3.6.Final or newer. Generally we strive for compatibility with a complete minor release family (4.3.x), but in this case we need to make use of some advanced SPIs only introduced in 4.3.6. The module ZIP we provide for WildFly contains an updated ORM module as well. This will be added along side the existing ORM module, which remains unchanged.

More natural association mappings in Neo4j

As part of our ongoing work on the Neo4j dialect, associations are mapped to relationships finally the way you'd expect it. There used to be redundant properties on associations which are gone now. Only actual association properties are stored on relationships, e.g. the order of the elements of an ordered list. The following shows an example:

Here we have an entity Father with an ordered collection of Child entities which is mapped by a relationship to each Child node. The birthorder attribute (the name has been given via @OrderColumn) is stored as property on the relationships, just as it naturally makes sense.

On a tangent, we've updated to Neo4j 2.1.3.

Simplified version management

Another big usage improvement for Maven users comes in form of our new Bill of Material POM (BOM). This POM defines a set of matching versions of the Hibernate OGM modules and their dependencies, such as Hibernate ORM, Hibernate Search or the different datatstore connectors.

All you need to do is to add this BOM to the dependencyManagement block of your project POM using the special import scope:

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

Then you can declare dependencies to Hibernate OGM or any of the related modules without specifying a version, which you will get automatically from the BOM:

<dependencies>
    <dependency>
        <groupId>org.hibernate.ogm</groupId>
        <artifactId>hibernate-ogm-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-search-orm</artifactId>
    </dependency>
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.1-api</artifactId>
    </dependency>
    ...
</dependencies>

To update to a new version of Hibernate OGM, simply update the referenced version of the BOM. This in turn will give you updated versions of any dependencies as required.

Your feedback matters

As we're approaching the Final release of Hibernate OGM 4.1 soon, your feedback matters more than ever! You can use the following tools to get in touch:

Sometimes life is full of surprises. And I can say I was quite surprised when I learned that Hibernate OGM has been nominated for this year's Duke's Choice Award.

Being nominated is a great honor for us, so kudos to those who brought this on its way! But winning the award would be even better; so go to java.net and vote for Hibernate OGM (upper right corner on the landing page). Every vote counts, and if you ever wanted to give back to Hibernate, this is your chance!

Hibernate OGM - What is it about and why should you vote for it?

In a word, Hibernate OGM (Object/Grid Mapper) gives you peace of mind when you need to persist Java domain models in NoSQL stores such as MongoDB, Infinispan or Neo4j. Based on the well-known semantics of JPA and re-using many parts of the proven Hibernate ORM engine, it provides simple access to this new world known as NoSQL.

For example consider an existing RDBMS-based application for address management which should be enhanced with some sort of friendship graph. Now handling and querying graph-like data is not exactly the specialty of RDBMS/SQL. Dedicated graph databases such as Neo4j are much better at this. With the help of Hibernate OGM, you could implement the friendship graph feature using the same persistence API you work with in the rest of the application. But for queries, you’d have the option to resort to powerful native queries written in Neo4j's Cypher language.

Hibernate OGM's vision is to enable applications to leverage those datastores being most beneficial for different use cases. Need deeply-nested hierarchical data? Use MongoDB. Need to distribute your data to hundreds of nodes with awesome performance? Use Infinispan. Need to work with graph-like data structures... You get the picture. But rather than using datastore-specific object mappers or even falling back to a store's native low-level API, you enjoy the comfort and power provided by the Hibernate engine.

Really, ORM for NoSQL?!

Now when we talk about this vision, we often get a glance from people which seems to ask But is JPA/ORM really a good fit for NoSQL?. To be honest, we were asking ourselves the same when starting the project. But over time it became apparent that the general idea of OxM (where x may stand for document, graph etc.) is not limited to relational datastores.

Most of JPA’s logical concepts - how do you define entities, their associations and so on - map excellently to NoSQL stores, sometimes arguably even better than to a RDMBS. Just to give an example, @ElementCollection is perfect for mapping nested dependent data in document stores such as MongoDB, which then can be accessed with a simple get, not requiring any joins; you don’t need to think about fetching strategies, orphan removal and the like.

Hibernate OGM benefits from many features of the Hibernate framework and the eco-system which has evolved around it. Any solution working with Hibernate will work with Hibernate OGM as well without further ado.

You need to validate your data but your store does not support check constraints or similar? No problem, just add Bean Validation constraints to your model and have them automatically validated when persisting your data. Your datastore doesn't provide sufficient query capabilities? Let Hibernate Search help you. It transparently indexes your data via Apache Lucene and allows to execute queries returning managed entities. If you like, even via JP-QL which is transformed into corresponding Lucene queries on the fly.

Of course you choose a certain store because of its specific capabilities, and not all of those may be exposed by a high-level abstraction such as JPA. Hibernate OGM gets out of your way as far as possible and for example allows you to specify queries in the store's native syntax (such as Cypher in the case of Neo4j). Also it's possible to apply store-specific options in a consistent and comfortable manner, via annotations or programmatically. For instance you can configure MongoDB's write concern and read preference settings individually for each of your mapped entities.

So is Hibernate OGM the perfect solution for all the possible challenges you may have when dealing with NoSQL?

Of course. NOT.

It will be very useful when dealing with well-defined domain models which need to be persisted, but as always there are situations in which an OxM tool may not be the best choice.

What's next?

The Hibernate OGM project has come a long way since its beginnings.

All the basics are in place, and at the moment we're fine-tuning some last details for the next release. It will be recommended for general usage and is to be expected soon. We're fixing some remaining glitches in the supported grid dialects and are validating that all the SPI contracts (which you may implement to add support for your favorite NoSQL store) are complete and correct. We’re also have a look on the performance side of things.

In future versions you may expect many more useful functionality such as support for true polyglot persistence (one domain model being spread across several data stores), implicit data migrations upon data load (for schema-less datastores) and declarative de-normalization of your data (ensuring fast retrieval in different use cases).

You like all this? Then don't forget to give your vote for the Duke's Choice Award on java.net to Hibernate OGM. And please spread the word about the project and ask your friends to vote for it, too! If you want to learn more, take a look at our reference documentation. Or check out a complete sample application which has been built for a session at Red Hat Summit earlier this year.

It's my great pleasure to announce the release of Hibernate OGM 4.1.0.Beta3. This release is focused on an improved experience when working with the Neo4j graph datastore and several improvements in the field of querying (the complete change log can be found here).

As always, you can either download a release bundle from SourceForge or retrieve the JARs from the JBoss Nexus repository server using Maven, Gradle etc. The GAV coordinates are:

  • org.hibernate.ogm:hibernate-ogm-core:4.1.0.Beta3 for the Hibernate OGM engine and
  • org.hibernate.ogm:hibernate-ogm-<datastore>:4.1.0.Beta3, depending on the backend you want to use.

Improved support for Neo4j

We now take advantage of labels - a new feature of Neo4J 2.x - to map entities in a more natural way. We use these labels to tag all the nodes belonging to one entity type. This does not only remove the need to put additional properties to the nodes but also will allow us to query for all the nodes of one entity type in an efficient manner.

We also support the execution of native Cypher queries now. You can either create them ad-hoc via EntityManager#createNativeQuery() or using the @NamedNativeQuery annotation on your entities:

@Entity
@NamedNativeQuery(
    name = "AnimalsBySpecies",
    query = "MATCH ( n: Animal { species: {species} } ) RETURN n",
    resultClass = Animal.class 
)
public class Animal { ... }
    
EntityManager em = ...
List<Animal> giraffes = em.createNamedQuery( "AnimalsBySpecies", Animal.class )
    .setParameter( "species", "Giraffe" )
    .getResultList();

As you can see in the example, native queries for Neo4j also support named parameters via the native Cypher parameter syntax.

The work on the Neo4j dialect is in full swing these days and you can expect to see further improvements in this field in the Beta4 release.

Query improvements

When working with queries you can now make use of setFirstResult() and setMaxResults() to page through a result set. This works for JP-QL as well as native MongoDB queries:

EntityManager em = ...;
List<Animal> giraffes = em.createQuery( "FROM Animal WHERE species = 'Giraffe'" )
    .setFirstResult( 51 )
    .setMaxResults( 100 )
    .getResultList();

Furthermore there is support for ORDER BY clauses in JP-QL queries now:

List<Animal> giraffes = em.createQuery( "FROM Animal WHERE species = 'Giraffe' ORDER BY name DESC" )
    .getResultList();

These two things together should be of great help when using Hibernate OGM to implement typical CRUD use cases (create, read, update, delete) on top of your NoSQL store.

What's next?

For Beta4 we plan to translate JP-QL queries into native Cypher queries for the Neo4j backend. We also got some ideas for performance improvements and will take a look into a more natural mapping of assocations to Neo4j relationships.

The MongoDB dialect should see some improvements around querying as well and we plan on investigating an error report and compensation API. This will offer the ability to collect errors on partially executed units of work on stores without full transactional semantics and the ability to react to these errors.

Needless to say, your feedback matters very much to us. So you're very welcome to raise your voice on the mailing list, ask questions in the forum or report any bugs or feature requests in the issue tracker.

19. Feb 2014, 20:59 CET, by Gunnar Morling

It's my great pleasure to announce the release of Hibernate OGM 4.1.0.Beta1! This version shines with:

  • support for CouchDB
  • query execution via JPA
  • new Option API
  • and much more, including a version bump

But wait, hasn't the last released version been 4.0.0.Beta4? That's true indeed, and in case you were wondering, we did not forget to do a final release of the 4.0 line. The reason for the version bump is that Hibernate OGM is now compatible with JPA 2.1 and Hibernate ORM 4.3. To reflect this we thought it'd be a good idea to jump to a new minor version as well.

As usual, you can get the release from SourceForge (ZIP, TAR.GZ) or retrieve it from the JBoss Nexus repository server using your favorite dependency management tool. The GAV coordinates are:

  • org.hibernate.ogm:hibernate-ogm-core:4.1.0.Beta1 for the OGM engine and
  • org.hibernate.ogm:hibernate-ogm-<datastore>:4.1.0.Beta1, depending on the backend you want to use.

Note that we did move some packages around, so make sure to look at our migration guide.

Enough of the introductory words, let's have a closer look at some of the new features.

Support for CouchDB

Based on a huge contribution of community member Andrea Boriero (thanks again, Andrea!), Hibernate OGM comes now with support for Apache CouchDB. CouchDB is a scalable document datastore which persists data as JSON documents and offers an HTTP API, fully embracing REST principles.

The storage strategy of the new dialect resembles that used for MongoDB. In particular we aimed for a very natural mapping of entities to documents in the datastore. E.g. properties are mapped as document fields, embeddables are mapped as nested documents etc. We're also leveraging CouchDB's built-in optimistic locking mechanism to detect concurrent updates, just as you would expect it.

The listing belows shows an entity and how it is represented as JSON document in CouchDB:

@Entity
public class News {

    @Id
    private String id;

    @Version
    @Generated
    @Column(name="_rev")
    private String revision;

    private String title;

    @Column(name="desc")
    private String description;

    //getters, setters ...
}

# JSON document
{
    "_id": "News:id_:news-1_",
    "_rev": "1-d1cd3b00a677a2e31cd0480a796e8480",
    "$type": "entity",
    "$table": "News",
    "title": "On the merits of NoSQL",
    "desc": "This paper discuss why NoSQL will save the world for good"
}

As you can see, the @Id attribute is mapped to CouchDB's reserved _id field, the same applies for the revision attribute which is mapped to _rev. The @Version and @Generated annotations advice OGM to handle the revision property as version attribute and use it for optimistic concurrency control. The @Column annotation can be used to map a property to a document field with another name.

To learn more about the CouchDB dialect and how to use it, refer to the reference guide. Note that the dialect is considered experimental at this time, so don't expect everything to work perfectly yet. Of course any feedback is highly welcome; maybe you even want to tackle one of the open issues) in this field?

Query improvements

We're very pleased to have progressed in the field of queries, addressing several long standing feature requests.

It's possible now to issue JP-QL queries via the EntityManager API which is great news for you if you're preferring JPA over using the native Hibernate API:

EntityManager em = ...;
List<Animal> giraffes = em.createQuery( "FROM Animal WHERE species = :species" )
    .setParameter( "species", "Giraffe" )
    .getResultList();

You also can work with named queries now:

@Entity
@NamedQuery(name = AnimalQueries.BY_SPECIES, query = "FROM Animal WHERE species = :species")
public class Animal { ... }

EntityManager em = ...;
List<Animal> giraffes = em.createNamedQuery( AnimalQueries.BY_SPECIES, Animal.class )
    .setParameter( "species", "Giraffe" )
    .getResultList();

Depending on the chosen backend, these queries will either be translated into Lucene Queries via Hibernate Search or into native queries of the backend (currently the case for MongoDB).

Option API

One big challenge Hibernate OGM has to deal with is how to expose store-specific functionality and configuration options in case the JPA semantics are not sufficient. Taking MongoDB as example, you might want to configure the write concern or a strategy for persisting association information.

Hibernate OGM now provides an extendible, type-safe and comprehensible mechanism for declaring such options. You can use annotations and a programmatic API. Dialect authors can plug in store-specific configuration options very easily, allowing users to specify these options in an intuitive and type-safe fashion. The following shows an example:

@Entity
@AssociationStorage(AssociationStorageType.ASSOCIATION_DOCUMENT)
public class Zoo {

    @OneToMany
    private Set<Animal> animals;

    @OneToMany
    private Set<Person> employees;

    @OneToMany
    @AssociationStorage(AssociationStorageType.IN_ENTITY)
    private Set<Person> visitors;

    //...
}

The @AssociationStorage annotation on the entity level expresses that all associations of the Zoo class should be persisted as separate association documents. Only the visitors association will be stored embedded within the corresponding Zoo document, as the local @AssociationStorage annotation takes precedence.

We try to share such configuration options between stores of one kind where feasible. E.g. the @AssocationStorage annotation is applicable to all document datastores (while e.g. an option such as @WriteConcern would be specific to MongoDB), simplifying the migration between stores. Neat, isn't it?

Now let's have a look at how you'd apply the same configuration using the programmatic API:

public class MyOptionConfigurator extends OptionConfigurator {

    @Override
    public void configure(Configurable configurable) {
        configurable.configureOptionsFor( MongoDB.class )
            .associationStorage( AssociationStorageType.ASSOCIATION_DOCUMENT )
            .entity( Zoo.class )
                .associationStorage( AssociationStorageType.IN_ENTITY )
                .property( "visitors", ElementType.FIELD )
                    .associationStorage( AssociationStorageType.ASSOCIATION_DOCUMENT )
                    .associationDocumentStorage( AssociationDocumentType.COLLECTION_PER_ASSOCIATION );
    }
}

All you need to do is to create an OptionConfigurator implementation, which provides access to the fluent configuration API. You can apply settings on a global level and then use entity() and property() to navigate to single entities and properties and apply options to the same. Again you can declare options specific to the store as well as options common to the family of store. Just don't forget to register your configurator when bootstrapping Hibernate OGM.

The work on options has been mainly behind the scenes in this release, with the shown options only being the first few examples for leveraging this new mechanism. You can expect to see more options specific to single stores or store families in future releases, providing you with all the flexibility you need to configure your datastore.

Streamlined configuration properties

The new option mechanism is an elegant way for specifying many options in a type-safe way. But plain properties in persistence.xml are just more appropriate for settings such as the host name of the store, user name etc. When working on the option API, it became apparent that several of our backend modules had the same or very similar configuration properties, but partly with different names and adhering to different naming conventions. So we took the chance to clean up the mess and re-organized the properties.

Properties common to all/most stores are named hibernate.ogm.datastore.* now, so e.g. there is hibernate.ogm.datastore.host, hibernate.ogm.datastore.username, hibernate.ogm.datastore.database etc. Properties specific to a single store are named hibernate.ogm.<datastore>.*, e.g. hibernate.ogm.mongodb.connection_timeout. Note that when programmatically bootstrapping a session factory or entity manager factory, you should refer to the properties using the constants declared on OgmProperties, InfinispanProperties etc.

While this change greatly increases consistency and removes redundancies, it requires existing applications to be adapted. So check out the reference guide to make sure you use the right names.

As always, your feedback around the new release is highly welcome. The complete change log can be found here. You can file bugs or feature requests in the issue tracker, ask questions in the forum or discuss ideas around the development of Hibernate OGM on our mailing list.

Showing 1 to 5 of 10 blog entries