Spring Data is a SpringSource project that aims to provide Spring's convenient programming model and well known conventions for NOSQL databases. Currently there is support for graph (Neo4j), key-value (Redis, Riak), document (MongoDB) and relational (Oracle) databases. Mark Pollack, the author of Spring.NET, is the project lead for the Spring Data project.
The Spring Data Neo4j project, as part of the Spring Data initiative, aims to simplify development with the Neo4j graph database. Like JPA, it uses annotations on simple POJO domain objects. The annotations activate one of the supported mapping approaches, either the copying, repository based one or the direct, attached, read- and write-through AspectJ based one. Both use the annotation and reflection metadata for mapping the POJO entities and their fields to nodes, relationships, and properties in the graph database.
Spring Data Neo4j allows, at anytime, to drop down to the Neo4j-API, see Chapter 19, Introduction to Neo4j level to execute functionality with the highest performance possible.
For Integration of Neo4j and Grails/GORM please refer to the Neo4j grails plugin. For other language bindings or frameworks visit the Neo4j Wiki.
The explanation of Spring Data Neo4js programming model starts with some underlying details. The basic internal workings of the Spring Data Neo4j mapping modes are explained in the initial chapter. Section 20.1, “Object Graph Mapping” covers the basic mapping and Section 20.2, “AspectJ support” contains details about the AspectJ version. It also explains some of the common issues around AspectJ tooling with the current IDEs.
To get started with a simple application, you need only your domain model and the annotations (see Section 20.4, “Defining node entities”) provided by the library. You use annotations to mark domain objects to be reflected by nodes and relationships of the graph database. For individual fields the annotations allow you to declare how they should be processed and mapped to the graph. For property fields and references to other entities this is straightforward.
To use advanced functionality like traversals, Cypher and Gremlin, a basic understanding of the graph data model is required. The graph data model is explained in the chapter about Neo4j, see Chapter 19, Introduction to Neo4j.
Relationships between entities are first class citizens in a graph database and therefore worth a separate chapter (Section 20.5, “Relating node entities”) describing their usage in Spring Data Neo4j.
Indexing operations are useful for finding individual nodes and relationships in a graph. They can be used to start graph operations or to be processed in your application. Indexing in the plain Neo4j API is a bit more involved. Spring Data Neo4j maintains automatic indexes per entity class, with @Indexed annotations on relevant fields. (Section 20.6, “Indexing”)
Being a Spring Data library, Spring Data Neo4j offers a comprehensive Neo4j-Template (Section 20.7, “Neo4jTemplate”) for interacting with the mapped entities and the Neo4j graph database. The operations provided by repositories per mapped entity class are based on the API offered by the Neo4j-Template. It also provides the operations of the Neo4j Core API in a more convenient way. Especially the querying (Indexes, Cypher, Gremlin and Traversals) and result conversion facilities allow writing very concise code.
Spring Data Commons provides a very powerful repository infrastructure that is also leveraged in Spring Data Neo4j. Those repositories just consist of a composition of interfaces that declare the available functionality in the each repository. The implementation-details of commonly used persistence methods are handled by the library. At least for typical CRUD, Index- and Query-operatoins that is very convenient. The repositories are extensible by annotated, named or derived finder methods. For custom implementations of repository methods you are free to add your own code. (Section 20.8, “CRUD with repositories”).
To be able to leverage the schema-free nature of Neo4j it is possible to project any entity to another entity type. That is useful as long as they share some properties (or relationships). The entities don't have to share any super-types or hierarchies. How that works is explained here: Section 20.9, “Projecting entities”.
Spring Data Neo4j also allows you to integrate with the powerful geospatial graph library Neo4j-Spatial that offers full support for working with any kind of geo-data. Spring Data Neo4j repositories expose a small bit of that via bounding-box and near-location searches. Section 20.10, “Geospatial Queries”.
To use fields that are dynamically backed by graph operations is a bit more involved. First you should know about traversals, Cypher queries and Gremlin expressions. Those are explained in Chapter 19, Introduction to Neo4jNeo4j-API. Then you can start using virtual, computed fields to your entities.
If you like the Active-Record approach that uses persistence methods mixed into the domain classes, you would want to look at the description of the additional entity methods (see Section 20.11, “Introduced methods”) that are added to your domain objects by Spring Data Neo4j Aspects . Those allow you to manage the entity lifecycles as well as to connect entities. Those methods also provide the means to execute the mentioned graph operations with your entity as a starting point.
Neo4j is an ACID database, it uses Java transactions (and internally even a 2 phase commit protocol) to guarantee the safety of your data. The implications of that are described in the chapter around transactions. (Section 20.12, “Transactions”)
The need of an active transaction for mutating the state of nodes or relationships implies that direct changes to the graph are only possible in a transactional context. Unfortunately many higher level application layers don't want to care about transactions and the open-session-in-view pattern is not widely used. Therefore Spring Data Neo4j introduced an entity lifecyle and added support for detached entities which can be used for temporary domain objects that are not intended to be stored in the graph or which will be attached to the graph only later. (Section 20.13, “Detached node entities”)
Unlike Neo4j which is a schema free database, Spring Data Neo4j works on Java domain objects. So it needs to store the type information of the entities in the graph to be able to reconstruct them when just nodes are retrieved. To achieve that it employs type-representation-strategies which are described in a separate chapter. (Section 20.14, “Entity type representation”)
Spring Data Neo4j offers basic support for bean property validation (JSR-303). Annotations from that JSR are recognized and evaluated whenever a property is set, or when a previously detached entity is persisted to the graph. (see Section 20.15, “Bean validation (JSR-303)”)
Unfortunately the setup of Spring Data Neo4j is more involved than we'd like. That is partly due to the maven setup
and dependencies, which can be alleviated by using different build systems like gradle or ant/ivy. The Spring configuration
itself boils down to two lines of <spring-neo4j> namespace setup. (see Chapter 21, Environment setup)
Spring Data Neo4j can also be used in a JPA environment to add graph features to your JPA entities. In the Chapter 22, Cross-store persistence the slightly different behavior and setup of a Graph-JPA interaction are described.
The provided samples, which are also publicly hosted on github are explained in Chapter 23, Sample code.
The performance implications of using Spring Data Neo4j are detailed in Chapter 24, Performance considerations. This chapter also discusses which usecases should be handled with Spring Data Neo4j and when it should not be used.
As AspectJ might not be well known to everyone, some of the core concepts of this Aspect oriented programming implementation for Java are explained in Chapter 25, AspectJ details.
How to consume the REST-API of a Neo4j-Server is the topic of Chapter 26, Neo4j Server. But Spring Data Neo4j can also be used to create custom Extensions for the Neo4j Server which would serve domain model abstractions to a suitable front-end. So instead of talking low level primitives to a database, the front-end or web-app would communicate via a domain level protocol with endpoints implemented in Jersey and Spring Data Neo4j.
As certain modes of Spring Data Neo4j are based on AspectJ and use some advanced features of that toolset, please be aware of that. Please see the section on AspectJ (Section 20.2, “AspectJ support”) for details if you run into any problems.