Hibernate.orgCommunity Documentation

Chapter 12. Neo4j

12.1. How to add Neo4j integration
12.2. Configuring Neo4j
12.3. Storage principles
12.3.1. Properties and built-in types
12.3.2. Entities
12.3.3. Associations
12.3.4. Auto-generated Values
12.3.5. Labels summary
12.4. Transactions
12.5. Queries
12.5.1. JP-QL queries
12.5.2. Cypher queries

Neo4j is a robust (fully ACID) transactional property graph database. This kind of databases are suited for those type of problems that can be represented with a graph like social relationships or road maps for example.

At the moment only the support for the embedded Neo4j is included in OGM.

1. Add the dependencies to your project

If your project uses Maven you can add this to the pom.xml:


Alternatively you can find the required libraries in the distribution package on SourceForge

2. Add the following properties:

hibernate.ogm.datastore.provider = neo4j_embedded
hibernate.ogm.neo4j.database_path = C:\example\mydb

The following properties are available to configure Neo4j support:

Hibernate OGM tries to make the mapping to the underlying datastore as natural as possible so that third party applications not using Hibernate OGM can still read and update the same datastore.

To make things simple, each entity is represented by a node, each embedded object is also represented by a node. Links between entities (whether to-one to to-many associations) are represented by relationships between nodes. Entity and embedded nodes are labelled ENTITY and EMBEDDED respectively.

Entities are stored as Neo4j nodes, which means each entity property will be translated into a property of the node. The name of the table mapping the entity is used as label.

You can use the name property of the @Table and @Column annotations to rename the label and the node’s properties.

An additional label ENTITY is added to the node.

Embedded elements are stored as separate nodes labeled with EMBEDDED.

The the type of the relationship that connects the entity node to the embedded node is the attribute name representing the embedded in the java class.

Note that in the previous examples no property is added to the relationships; in the following one, one property is added to keep track of the order of the elements in the list.

An association, bidirectional or unidirectional, is always mapped using one relationship, beginning at the owning side of the association. This is possible because in Neo4j relationships can be navigated in both directions.

The type of the relationships depends on the type of the association, but in general it is the role of the association on the main side. The only property stored on the relationship is going to be the index of the association when required, for example when the association is annotated with @OrderColumn or when a java.util.Map is used.

In Neo4j nodes are connected via relationship, this means that we don’t need to create properties which store foreign column keys. This means that annotation like @JoinColumn won’t have any effect.

Hibernate OGM supports the table generation strategy as well as the sequence generation strategy with Neo4j. It is generally recommended to work with the latter, as it allows a slightly more efficient querying for the next sequence value.

Sequence-based generators are represented by nodes in the following form:

Each sequence generator node is labelled with SEQUENCE. The sequence name can be specified via @SequenceGenerator#sequenceName(). A unique constraint is applied to the property sequence_name in order to ensure uniqueness of sequences.

If required, you can set the initial value of a sequence and the increment size via @SequenceGenerator#initialValue() and @SequenceGenerator#allocationSize(), respectively. The options @SequenceGenerator#catalog() and @SequenceGenerator#schema() are not supported.

Table-based generators are represented by nodes in the following form:

Each table generator node is labelled with TABLE_BASED_SEQUENCE and the table name as specified via @TableGenerator#table(). The sequence name is to be given via @TableGenerator#pkColumnValue(). The node properties holding the sequence name and value can be configured via @TableGenerator#pkColumnName() and @TableGenerator#valueColumnName(), respectively. A unique constraint is applied to the property sequence_name to avoid the same sequence name is used twice within the same "table".

If required, you can set the initial value of a sequence and the increment size via @TableGenerator#initialValue() and @TableGenerator#allocationSize(), respectively. The options @TableGenerator#catalog(), @TableGenerator#schema(), @TableGenerator#uniqueConstraints() and @TableGenerator#indexes() are not supported.

Unless a different org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform is specified, Hibernate OGM will use a specific implementation to integrate with the Neo4j transaction mechanism. This means that you can start and commit transaction using the Hibernate session.

The drawback is that it is not possible at the moment to let Neo4j participate in managed JTA transactions spanning several resources (see issue OGM-370).

You can express queries in a few different ways:

While you can use JP-QL for simple queries, you might hit limitations. The current recommended approach is to use native Cypher queries if your query involves nested (list of) elements.

Hibernate OGM also supports Cypher queries for Neo4j. You can execute Cypher queries as shown in the following example:

The result of a query is a managed entity (or a list thereof) or a projection of attributes in form of an object array, just like you would get from a JP-QL query.

Native queries can also be created using the @NamedNativeQuery annotation:

Hibernate OGM stores data in a natural way so you can still execute queries using your favorite tool, the main drawback is that the results are going to be raw Neo4j elements and not managed entities.