Red Hat

In Relation To

The Hibernate team blog on everything data.

Meet Mark Paluch, a true open-source champion

Posted by Vlad Mihalcea    |       |    Tagged as Discussions Hibernate OGM

In this post, I’d like you to meet Mark Paluch, who, among other projects, is one of our Hibernate OGM project contributors.

  1. Hi, Mark. Would you like to introduce yourself and tell us what you are currently working on?

    I am Mark Paluch, and I am working for Pivotal Software as Spring Data Engineer. I am a member of the JSR 365 EG (CDI 2.0), project lead of the lettuce Redis driver, and I run a couple of other open source projects. I enjoy tinkering on Internet of Things projects in my spare time. Before I joined Pivotal, I worked since the early 2000’s as a freelancer in a variety of projects using Java SE/EE and web technologies. My focus lies now on Spring Data with Redis, Cassandra, and MongoDB in particular.

  2. You have contributed a lot to the Hibernate OGM Redis module. Can you please tell us a little bit about Redis?

    I was not the first one bringing up the idea of Redis support in Hibernate OGM. In fact, Seiya Kawashima did a pretty decent job with his pull-request but at some point, Hibernate OGM development and the PR diverged. I came across the pull request and picked it up from there.

    Redis is an in-memory data structure store, used as database, cache and message broker. It originated from a key-value store but evolved by supporting various data structures like lists, sets, hashes and much more. Redis is blazing-fast although it runs mostly single-threaded. Its performance originates in a concise implementation and that all operations are performed in-memory. This does not mean that Redis has no persistence. Redis is configured by default to store data on disk and disk I/O is asynchronous. Redis facilitates through its versatile nature an enormous number of use-cases such as Caching, queues, remote locking, just storing data and much more. An important fact to me is always that I’d never use Redis for data I cannot recover as wiping data from Redis is just too easy but using it as semi-persistent a store is the perfect use.

  3. You are also the author of the Lettuce open source project. How does it compare to Hibernate OGM?

    Hibernate OGM and lettuce are projects with different aims. Lettuce is a driver/Java-binding for Redis. It gives Java developers access to the Redis API using synchronous, asynchronous and reactive API bindings. You can invoke the Redis API with lettuce directly and get the most out of Redis if you need it. Any JDBC driver is situated on a similar abstraction level as lettuce except for some specific features. lettuce does not require connection-pooling and dealing with broken connections as it allows users to benefit from auto-reconnection and thread-safe connections. Hibernate OGM Redis uses this infrastructure and provides its data mapping features on top of lettuce.

  4. What benefit do you think Hibernate OGM offers to application developers compared to using the NoSQL API directly?

    Each NoSQL data store has its own, very specific API. Native APIs require developers not only get familiar with the data store traits but also with its API. Redis API comes with over 150 commands that translate to 650+ commands with sub-command permutations.

    Every Redis command is very specific and behaves on its own. The Redis command documentation provides detailed insight to commands, but users are required to spend a fair amount of their time to get along with the native API.

    Hibernate OGM applies elements from the JPA spec to NoSQL data stores and comes up with an API that Java EE/JPA developers are familiar. Hibernate OGM lowers barriers to entry. Hibernate OGM comes with a purpose of mapping data into a NoSQL data store. Mapping simple JPA entities to the underlying data store works fine but sometimes, like associations or transactions, do not map well to MongoDB and Redis. Users of Hibernate OGM need to be aware of the underlying persistence technology to get familiar with its concepts and strengths as well with their limitations.

    I also see a great advantage of the uniform configuration mechanism of Hibernate OGM. Every individual datastore driver comes up with its individual configuration method. Hibernate OGM unifies the styles into a common approach. One item on my wish list for Hibernate OGM is JDNI/WildFly configuration support to achieve similar flexibility as it is possible with JDBC data sources.

  5. Do you plan on supporting Hibernate OGM in Spring Data as well?

    Hibernate OGM and Spring Data follow both the idea of supporting NoSQL data stores. Hibernate OGM employs several features from NoSQL data stores to enhance its data mapping centering around JPA. JPA is an inherently relational API, which talks about concepts that are not necessarily transferable to the NoSQL world. Spring Data comes with modules for various popular data stores with a different approach to providing a consistent programming model for the supported stores but not try to force everything into a single abstracting API. Spring Data Modules provide multiple levels of abstraction on top of the NoSQL data store APIs. Core concepts of NoSQL data stores are exposed through an API that commonly looks and feels like Spring endpoints. Hibernate OGM can already be used together with Spring Data JPA. A good use-case is the Spring Data Repositories abstraction which provides a uniform interface to access data from various data stores that do not require users to write a query language and leverages store-specific features.

Thank you, Mark, for taking your time. It is a great honor to have you here. To reach Mark, you can follow him on Twitter.

After over 60 resolved tasks, we’re proud to release Hibernate Search version 5.6.0.Beta1.

The Elasticsearch integration made significant progress, and we believe it to be ready for wider usage.

Progress of the Elasticsearch integration

Improvements since the previous milestone:

MassIndexer

significant better performance as it now uses bulk operations.

Calendar, Dates, numbers and mapping details

several corrections and improvements were made to produce a cleaner schema.

Cluster state

we now wait for a newly started Elasticsearch cluster to be "green" - or optionally "yellow" - before starting to use it.

WildFly modules

a critical bug was resolved, the modules should work fine now.

Many more

for a full list of all 63 improvements, see this JIRA query.

What is missing yet?

Performance testing

we didn’t do much performance testing, it’s probably not as efficient as it could be.

Relax the expected Elasticsearch version

it’s being tested with version 2.3.1 but we have plans to support a wider range of versions.

Explicit refresh requests

we plan to add methods to issue an indexreader refresh request, as the changes pushed to Elasticsearch are not immediately visible by default.

Your Feedback!

we think it’s in pretty good shape, it would be great for more people to try it out and let us know what is missing and how it’s working for you.

Notable differences between using embededd Lucene vs Elasticsearch

Unless you reconfigure Hibernate Search to use an async worker, by default when using the Lucene backend after you commit a transaction the changes to the index are immediately applied and any subsequent search will "see" the changes. On Elasticsearch the default is different: changes received by the cluster are only "visible" to searches after some seconds (1 by default).

You can reconfigure Hibernate Search to force a refresh of indexes after each write operation by using the hibernate.search.default.elasticsearch.refresh_after_write configuration setting.

This setting defaults to false as that’s the recommended setting for optimal performance on Elasticsearch. You might want to set this to true to make it simpler to write unit tests, but you should take care to not rely on the synchronous behaviour for your production code.

Improvements for embedded Lucene users

While working on Elasticsearch, we also applied some performance improvements which apply to users of the traditional Lucene embedded users.

Special thanks to Andrej Golovnin, who contributed several patches to reduce allocation of objects on the hot path and improve overall performance.

How to get this release

Everything you need is available on Hibernate Search’s web site.

Get it from Maven Central using the above coordinates.

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.

Meet Sergey Chernolyas

Posted by Vlad Mihalcea    |       |    Tagged as Discussions Hibernate OGM

In this post, I’d like you to meet Sergey Chernolyas who is one of our Hibernate OGM project contributors.

  1. Hi, Sergey. You are one of the people who contributed to the Hibernate OGM project. Can you please introduce yourself?

    Hi, Vlad! My name is Sergey Chernolyas. I am from Russia, and I am 38 years old. I have been working with Java technologies since 2000. During my career, I got four certificates on Java technologies from Oracle and got involved in many development and integration projects.

  2. Can you tell us what project are you currently working on and if it uses Hibernate OGM?

    Now, I am working on a new module for Hibernate OGM, which aims to integrate the OrientDB NoSQL database. With this module, OGM will support a total of 7 NoSQL databases. Although at my current job, my work is not related to NoSQL solutions or Hibernate OGM, I am interested in this topic, and that’s why I pushed myself to learn Hibernate OGM and exploring NoSQL databases.

  3. Can you tell us a little about OrientDB?

    OrientDB is a graph-oriented and document-oriented database, and it is built using Java technologies. Briefly, the main advantages of using OrientDB are:

    1. It can operate in several modes: as an in-memory database, or through a network connection, or it can be store data in a local file.

    2. It offers join-less entity associations.

    3. It supports stored procedures that may be written in Java, JavaScript and any other language implementing the JSR-223 specification (e.g. Groovy, JRuby, etc.).

    4. It has good performance and is Big Data-oriented.

      For more details about OrientDB, you can visit the official documentation. Recently, the OrientDB team released the 2.2 GA version, so it’s worth giving it a try.

  4. What is the main benefit of using Hibernate OGM for accessing OrientDB over using their native API?

    The main benefit of using Hibernate OGM over the native API is the standard way for application development. Also, Hibernate OGM hides many low-level operations for creating and managing database connections, or for executing queries.

    While implementing the first version of the OrientDB Hibernate OGM module, I was faced with some OrientDB issues that prevented me integrate all features that ought to be supported by any Hibernate OGM module. Luckily, the OrientDB team was helpful and supportive, and I hope that by the time I finish this integration, the OrientDB team had already fixed my previously reported issues.

Thank you, Sergey for taking your time, and keep up the good work.

Hibernate OGM 5 is out!

Posted by Davide D'Alto    |       |    Tagged as Hibernate OGM Releases

Hibernate OGM 5.0.0.Final is finally here!

What’s new?

Compared to the 4.2.Final, this version includes:

There are also several bug fixes and you can find all the details in the changelog.

A nice Getting started guide is available on our website for people who want to start playing with it. A more in depth explanation of all the details around Hibernate OGM is in the reference documentation.

If you need to upgrade from a previous version, you can find help on the migration notes.

What’s coming next?

Now that Hibernate OGM 5 is out, we can focus on working on some new integrations like Neo4j remote and Hot Rod.

You can also have a look at the roadmap for up-to-date news about what’s coming next.

If you think that something is missing or if you have some opinion about what we should include, please, let us hear your voice.

Where can I get it?

You can get Hibernate OGM 5.0.0.Final core via Maven using the following coordinates:

  • org.hibernate.ogm:hibernate-ogm-core:5.0.0.Final

and these are the back-ends currently available:

  • Cassandra: org.hibernate.ogm:hibernate-ogm-cassandra:5.0.0.Final

  • CouchDB: org.hibernate.ogm:hibernate-ogm-couchdb:5.0.0.Final

  • Infinispan: org.hibernate.ogm:hibernate-ogm-infinispan:5.0.0.Final

  • Ehcache: org.hibernate.ogm:hibernate-ogm-ehcache:5.0.0.Final

  • MongoDB: org.hibernate.ogm:hibernate-ogm-mongodb:5.0.0.Final

  • Neo4j: org.hibernate.ogm:hibernate-ogm-neo4j:5.0.0.Final

  • Redis: org.hibernate.ogm:hibernate-ogm-redis:5.0.0.Final

Alternatively, you can download archives containing all the binaries, source code and documentation from SourceForge.

How can I get in touch?

You can find us through the following channels:

We are looking forward to hear your feedback!

Hibernate Community Newsletter 10/2016

Posted by Vlad Mihalcea    |       |    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.

Events

C2B2 and Red Hat are hosting a Hibernate Q&A event, so if you are in London on May 24th, you now have the opportunity of meeting some of the developers that are behind Hibernate ORM, OGM, Search, and Validator.

Articles

Videos

The Devoxx France 2016 videos are available on YouTube, so, if you know French, you should definitely watch Emmanuel Bernard' talks on Hibernate projects latest features, as well as the one about the Elasticsearch support that is being integrated into Hibernate Search.

If you want to learn how to boost your data access layer performance, you should check my High-Performance Hibernate talk as well.

While the team has been busy implementing great new features such as the Elasticsearch integration for the next 5.6 release, some of you provided interesting feedback on our stable release.

The summary of the feedback I heard is that migrating to the new sorting requirements can be confusing, and there were some issues with our Faceting implementation.

Hibernate Search version 5.5.3.Final is available now, fixing the reported issues and improving the error messages around sorting.

The changelog is rather small, so this time I’ll post it verbatim:

  • HSEARCH-1917 - Cannot index null or empty values for faceted fields

  • HSEARCH-2082 - Documentation refers to @SortField when it should be @SortableField

  • HSEARCH-2085 - Typo in hibernate-search-engine logger

  • HSEARCH-2086 - Long and Date range faceting doesn’t honor hasZeroCountsIncluded

  • HSEARCH-2179 - Hanging during shutdown of SyncWorkProcessor

  • HSEARCH-2193 - LuceneBackendQueueTask does not release the Directory lock on update failures

  • HSEARCH-2200 - Typo in log message

  • HSEARCH-2240 - Parallel service lookup might fail to find the service

  • HSEARCH-2199 - Allows the use of CharFilter in the programmatic API of SearchMapping

  • HSEARCH-2084 - Upgrade to WildFly 10.0.0.Final

  • HSEARCH-2089 - Ensure the performance tests do not use the WildFly embedded version of Search

  • HSEARCH-1951 - Improve resulting error message when applying the wrong Sort Type

  • HSEARCH-2090 - Using the wrong header in the distribution/pom.xml

  • HSEARCH-2241 - Clarify deprecation of setFilter() method on FullTextQuery

Spot inefficient sorting operations easily in test suites

While Hibernate Search already would log a warning when forced to perform a query using a sub-optimal sorting strategy, that wasn’t making it very easy to spot mapping or usage mistakes.

Set this property:

    hibernate.search.index_uninverting_allowed = false

and you’ll have your tests fail with an exception rather than log warnings.

This property is not new in this release, but it’s worth reminding as it makes it much easier to validate your migrations from previous versions.

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-search-orm</artifactId>
   <version>5.5.3.Final</version>
</dependency>
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>5.0.6.Final</version>
</dependency>
<dependency>
   <groupId>org.apache.lucene</groupId>
   <artifactId>lucene-core</artifactId>
   <version>5.3.1</version>
</dependency>

What are we working on?

The Elasticsearch integration is almost feature complete, we expect to be able to release a Beta1 version in some weeks.

How to get this release

Everything you need is available on Hibernate Search’s web site. Download the full distribution from here, or get it from Maven Central using the above coordinates, and don’t hesitate to reach us in our forums or mailing lists.

Hibernate Community Newsletter 9/2016

Posted by Vlad Mihalcea    |       |    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

Presentations

Both Emmanuel and I have been presenting at Devoxx France, and we are going to share the videos once they are available. Meanwhile, you can checkout the slides for the High-Performance Hibernate presentation.

Emulating property literals with Java 8 method references

Posted by Gunnar Morling    |       |    Tagged as Discussions

One of the things library developers often miss in Java are property literals. In this post I’m going to show how to make creative use of Java 8 method references to emulate property literals, with the help of some byte code generation.

Akin to class literals (e.g. Customer.class), property literals would allow to refer to the properties of a bean class in a type-safe manner. This would be useful for designing APIs that run actions on specific bean properties or apply some means of configuration to them. E.g. consider the API for programmatic configuration of index mappings in Hibernate Search:

new SearchMapping().entity( Address.class )
    .indexed()
    .property( "city", ElementType.METHOD )
        .field();

Or the validateValue() method from the Bean Validation API for validating a value against the constraints of a single property:

Set<ConstraintViolation<Address>> violations = validator.validateValue( Address.class, "city", "Purbeck" );

In both cases a String is used to represent the city property of the Address class.

That’s error-prone on several levels:

  • The Address class might not have a property city at all. Or one could forget to update that String reference when renaming the property.

  • In the case of validateValue(), there is no way for making sure that the passed value actually satisfies the type of the city property.

Users of the APIs will only find out about these issues when actually running their application. Wouldn’t it be nice if instead the compiler and the language’s type system prevented such wrong usages from the beginning? If Java had property literals, that’d be exactly what you’d get (invented syntax, this does not compile!):

mapping.entity( Address.class )
    .indexed()
    .property( Address::city, ElementType.METHOD )
        .field();

And:

validator.validateValue( Address.class, Address::city, "Purbeck" );

The issues mentioned above would be avoided: Having a typo in a property literal would cause a compilation error which you’d notice right in your IDE. It’d allow to design the configuration API in Hibernate Search in a way to accept only properties of Address when configuring the Address entity. And in case of Bean Validation’s validateValue(), literals could help to ensure that only values can be passed, that are assignable to the property type in question.

Java 8 method references

While Java 8 has no real property literals (and their introduction isn’t planned for Java 9 either), it provides an interesting way to emulate them to some degree: method references. Having been introduced to improve the developer experience when using Lambda expressions, method references also can be leveraged as poor-man’s property literals.

The idea is to consider a reference to a getter method as a property literal:

validator.validateValue( Address.class, Address::getCity, "Purbeck" );

Obviously, this will only work if there actually is a getter. But if your classes are following JavaBeans conventions - which often is the case - that’s fine.

Now how would the definition of the validateValue() method look like? The key is using the new Function type:

public <T, P> Set<ConstraintViolation<T>> validateValue(Class<T> type, Function<? super T, P> property, P value);

By using two type parameters, we make sure that the bean type, the property and the value passed for the property all correctly match. So API-wise, we got what we need: It’s safe to use, and the IDE will even auto-complete method names after starting to write Address::. But how do we derive the property name from the Function in the implementation of validateValue()?

That’s where the fun begins, as the Function interface just defines a single method, apply(), wich runs the function against a given instance of T. That seems not exactly helpful, does it?

ByteBuddy to the rescue

As it turns out, applying the function actually does the trick! By creating a proxy instance of the T type, we have a target for invoking the method and can obtain its name in the proxy’s method invocation handler.

Java comes with support for dynamic proxies out of the box, but that’s limited to proxying interfaces only. As our API should work with any kind of bean, also actual classes, I’m going to use a neat tool called ByteBuddy instead. ByteBuddy provides an easy-to-use DSL for creating classes on the fly which is exactly what we need.

Let’s begin by defining an interface which just allows to store and obtain the name of a property we obtained from a method reference:

public interface PropertyNameCapturer {

    String getPropertyName();

    void setPropertyName(String propertyName);
}

Now let’s use ByteBudy to programmatically create a proxy class which is assignable to the type of interest (e.g. Address) and PropertyNameCapturer:

public <T> T /* & PropertyNameCapturer */ getPropertyNameCapturer(Class<T> type) {
    DynamicType.Builder<?> builder = new ByteBuddy()                                       (1)
            .subclass( type.isInterface() ? Object.class : type );

    if ( type.isInterface() ) {                                                            (2)
        builder = builder.implement( type );
    }

    Class<?> proxyType = builder
        .implement( PropertyNameCapturer.class )                                           (3)
        .defineField( "propertyName", String.class, Visibility.PRIVATE )
        .method( ElementMatchers.any() )                                                   (4)
            .intercept( MethodDelegation.to( PropertyNameCapturingInterceptor.class ) )
        .method( named( "setPropertyName" ).or( named( "getPropertyName" ) ) )             (5)
            .intercept( FieldAccessor.ofBeanProperty() )
        .make()
        .load(                                                                             (6)
             PropertyNameCapturer.class.getClassLoader(),
             ClassLoadingStrategy.Default.WRAPPER
        )
        .getLoaded();

    try {
        @SuppressWarnings("unchecked")
        Class<T> typed = (Class<T>) proxyType;
        return typed.newInstance();                                                        (7)
    }
    catch (InstantiationException | IllegalAccessException e) {
        throw new HibernateException(
            "Couldn't instantiate proxy for method name retrieval", e
        );
    }
}

The code may appear a bit dense, so let me run you through it. First we obtain a new ByteBuddy instance (1) which is the entry point into the DSL. It is used to create a new dynamic type that either extends the given type (if it is a class) or extends Object and implements the given type if it is an interface (2).

Next, we let the type implement the PropertyNameCapturer interface and add a field for storing the name of the specified property (3). Then we say that invocations to all methods should be intercepted by PropertyNameCapturingInterceptor (we’ll come to that in a moment) (4). Only setPropertyName() and getPropertyName() (as declared in the PropertyNameCapturer interface) should be routed to write and read access of the field created before (5). Finally, the class is built, loaded (6) and instantiated (7).

That’s all that’s needed to create the proxy type; Thanks to ByteBuddy, this is done in a few lines of code. Now let’s take a look at the interceptor we configured before:

public class PropertyNameCapturingInterceptor {

    @RuntimeType
    public static Object intercept(@This PropertyNameCapturer capturer, @Origin Method method) {         (1)
        capturer.setPropertyName( getPropertyName( method ) );                                           (2)

        if ( method.getReturnType() == byte.class ) {                                                    (3)
            return (byte) 0;
        }
        else if ( ... ) { } // ... handle all primitve types
            // ...
        }
        else {
            return null;
        }
    }

    private static String getPropertyName(Method method) {                                               (4)
        final boolean hasGetterSignature = method.getParameterTypes().length == 0
                && method.getReturnType() != null;

        String name = method.getName();
        String propName = null;

        if ( hasGetterSignature ) {
            if ( name.startsWith( "get" ) && hasGetterSignature ) {
                propName = name.substring( 3, 4 ).toLowerCase() + name.substring( 4 );
            }
            else if ( name.startsWith( "is" ) && hasGetterSignature ) {
                propName = name.substring( 2, 3 ).toLowerCase() + name.substring( 3 );
            }
        }
        else {
            throw new HibernateException( "Only property getter methods are expected to be passed" );    (5)
        }

        return propName;
    }
}

intercept() accepts the Method being invoked as well as the target of the invocation (1). The annotations @Origin and @This are used to designate the respective parameters so ByteBuddy can generate the correct invocations of intercept() into the dynamic proxy type.

Note that there is no strong dependency from this interceptor to any types of ByteBuddy, meaning that ByteBuddy is only needed when creating that dynamic proxy type but not later on, when actually using it.

Via getPropertyName() (4) we then obtain the name of the property represented by the passed method object and store it in the PropertyNameCapturer (2). If the given method doesn’t represent a getter method, an exception is raised (5). The return value of the invoked getter is irrelevant, so we just make sure to return a sensible "null value" matching the property type (3).

With that, we got everything in place to get hold of the property represented by a method reference passed to validateValue():

public <T, P> Set<ConstraintViolation<T>> validateValue(Class<T> type, Function<? super T, P> property, P value) {
    T capturer = getPropertyNameCapturer( type );
    property.apply( capturer );
    String propertyName = ( (PropertyLiteralCapturer) capturer ).getPropertyName();

    // perform validation of the property value...
}

When applying the function to the property name capturing proxy, the interceptor will kick in, obtain the property name from the Method object and store it in the capturer instance, from where it can be retrieved finally.

And there you have it, some byte code magic lets us make creative use of Java 8 method references for emulating property literals.

That said, having real property literals as part of the language (dreaming for a moment, maybe Java 10?) would still be very beneficial. It’d allow to deal with private properties and, hopefully, one could refer to property literals from within annotations. Real property literals also would be more concise (no "get" prefix) and it’d generally feel a tad less hackish ;)

Hibernate Community Newsletter 8/2016

Posted by Vlad Mihalcea    |       |    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

Presentations

We are getting closer and closer to the final release of Hibernate OGM 5.

This release includes support for Redis Cluster and a new dialect to store data within Redis hashes; java.util.UUID are now using the native uuid type in Apache Cassandra; more queries are now supported using the MongoDB CLI syntax.

This release is also aligned to the Hibernate 5 family and it will work with Hibernate ORM 5, Hibernate Search 5.5 and the latest WildFly 10. Check the previous post for more details about it.

The migration notes contains more information about migrating from earlier versions of Hibernate OGM to 5.x.

Have a look at the change log for a list of everything included in this release.

Redis Cluster support

Enabling the support for Redis Cluster is a matter of setting the following property to true:

hibernate.ogm.redis.cluster = true

When this property is enabled, data will be stored across Redis cluster nodes according to the Redis key distribution model on the hash slot of the key of each entity.

Check the documentation for more details about the configuration options for Redis in Hibernate OGM.

Redis hash mapping

When using this mapping, data is stored using key-values pairs using Redis hashes. The benefit of this approach is that it allows partial updates.

You can enable this dialect setting the following property:

hibernate.ogm.datastore.grid_dialect = org.hibernate.ogm.datastore.redis.RedisHashDialect

This will map the following entity:

@Entity
public class News {

    @Id
    private String id;

    @Version
    @Column(name="version")
    private int version;

    private String title;

    private String description;

    //getters, setters ...
}

with the following properties:

version     = 1
title       = On the merits of NoSQL
description = This paper discuss why NoSQL will save the world for good

A huge thanks to community member Mark Paluch, responsible for both these great improvements in the Redis area. Note that these features are both experimental for the time being.

Additional MongoDB native CLI queries support

Thanks to the contribution of Thorsten Möller, Hibernate OGM now supports more type of queries using the MongoDB CLI syntax: findOne, findAndModify, insert, remove and update.

Here an example showing how you can use them:

OgmSession session = ...

String nativeQuery = "db.OscarWilde.findAndModify({"
        + "'query': {'author': 'oscarwilde'}, "
        + "'update': { '$set': { 'author': 'Oscar Wilder' } }, "
        + "'new': true "
        + "})";

Query query = session.createNativeQuery( nativeQuery ).addEntity( OscarWilde.class );
List<OscarWilde> result = query.list();

You can find more details in the documentation about experimental support of native MongoDB queries.

What’s coming next?

We are working on the Neo4j remote dialect and we are focused on releasing a stable version of Hibernate OGM 5.

Where can I get it?

You can get Hibernate OGM 5.0.0.CR1 via Maven etc. using the following coordinates:

  • org.hibernate.ogm:hibernate-ogm-core:5.0.0.CR1 for the Hibernate OGM core module

  • org.hibernate.ogm:hibernate-ogm-<%BACKEND%>:5.0.0.CR1 for the NoSQL backend you want to use, with _<%BACKEND%> being one of "mongodb", "redis", "neo4j", etc.

Alternatively, you can download archives containing all the binaries, source code and documentation from SourceForge.

How can I get in touch?

You can get in touch through the following channels:

We are looking forward to hear your feedback!

back to top