Spring Data Neo4j Progress Update: SDN 3 & Neo4j 2


The 3.0.1 Release

Spring Data Neo4j 3.0 was recently rolled out by the Spring Data team as part of the “Codd” release train of the Spring Data projects. We’re happy to announce this milestone, which can be used effective immediately to start developing Neo4j 2.0 applications with Spring. Today, Spring Data Neo4j 3.0.1 containing some necessary updates was released.

The Spring Data Neo4j 3 release required a significant update of the code-base in order to support the new features and changes in Neo4j 2.0. Many of these changes included refactoring to accommodate mandatory read transactions and the removal of the reference node, as well as the required transaction-separation for schema operations. Those affected Spring Data Neo4j itself, as well as many of the dependent libraries.

We’re happy to have a first release that supports Neo4j 2.0, and that you can start developing with. We still have a few issues to work out before we recommend putting Spring Data Neo4j 3 into production, and we ask you to bear with us as we work on these last few areas. We will be releasing them as updates in the coming weeks, as soon as is possible. Please send us feedback if you run into any issues!

What has changed?

Spring Data Neo4j now works with and only with Neo4j 2.x. By default your entity types are represented as labels on the nodes and indexed simple properties are handled by Neo4j schema indexes. Queries on repositories support Neo4j 2.0 Cypher syntax and derived finders are automatically using labels, the new Cypher syntax and schema indexes.

Type Representation

A new label based type representation strategy has been added, and is now the default. Additionally, the whole inheritance hierarchy of annotated NodeEntities is actually added to each node to allow lookup on each level.

NoteThe default naming for type representation has changed from the fully qualified class name to just the simple name of the class. This allows for a nicer graph model and also easier refactorings. You can still declare your own naming using the @TypeAlias annotation.

Schema Indexes

We also support schema indexes, in fact they became the default. So when you annotate your entity like this:

@NodeEntity class Person {
@Indexed(unique=true) String ssid;
@Indexed String name;
int age;
@RelatedTo(direction=BOTH) Collection<Person> friends;
}
the following indexes will be created at startup:
CREATE INDEX ON :Person(name);
CREATE CONSTRAINT ON (p:Person) ASSERT p.ssid IS UNIQUE;

Those indexes will automatically be used for appropriate queries

NoteThe unique entity creation that would normally use unique constraints MERGE is not implemented yet. So if you rely on that mechanism, please configure your indexed unique fields to use the indexType=SIMPLE

Derived Finder Methods

Quite a lot of work also went into the generation of Cypher queries for derived finder methods. These now take labels and schema indexes into account.

So for the Person entity above and the following finder methods, the queries listed in the comments will be generated for this repository. Under the hood Cypher then uses schema information to take care of lookups (or label scan + property filtering).

interface PersonRepository extends GraphRepository<Person> {
// MATCH (p) WHERE p:Person AND p.name = {name}
List<Person> findByName(@Param("name") String name);
// MATCH (p) WHERE p:Person AND p.age > {0}
Collection<Person> findByAgeGreaterThan(int age);
// MATCH (p)-[:FRIEND]-(f) WHERE p:Person and id(f) = {0}
Set<Person> findByFriends(Person friend);
}

Legacy Indexes

Legacy indexes are still accessible, however if you want to use them you need to explicitly specify this with @Indexed(indexType=SIMPLE), same goes for numeric indexes for range queries.Fulltext and spatial indexes also still rely on the legacy index implementations, but they were configured separately anyway. Several of the APIs related to legacy indexes have been marked as deprecated as part of this change.

Data-Migration

At present there is no migration utility. You can upgrade your Neo4j store from 1.9 to 2.0 using the Neo4j allow_store_upgrade=true configuration setting. Schema indexes are automatically created at startup and data of nodes with the corresponding labels is re-indexed. The only thing that is not updated automatically is the type-representation. You might use a cypher statement like this to do it.

// superclass
START n=node:__types__(className=”com.example.domain.Person”)
SET n:Person
WHERE n.__type__ = ”com.example.domain.Person”
SET n:_Person

// subclass
START n=node:__types__(className=”com.example.domain.Employee”)
SET n:Employee:_Employee

For testing Spring Data Neo4j 3.0.1 and providing feedback it shouldn’t be a problem to import some data into it. For the next minor release we’ll work on providing a migration tool though.

Setup & Configuration

As usual, you add Spring Data Neo4j 3.0 as a dependency to your pom.xml

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>

Neo4j 2.0 introduced the requirement separately manage schema and data transactions. We tried several approaches to handle this automatically, none of which worked in a satisfactory manner. This has resulted in a few breaking changes which needed to be introduced in order to cater for this and is detailed below.

ImportantSo we had to make the entity metadata handling an explicit step in the lifecycle and decided to change the base-package attribute for neo4j:config to be mandatory. It allows for one or more (comma separated) package names to be scanned for entities.
<neo4j:config storeDir="graph.db" base-package="com.example.domain"/>
<neo4j:repositories base-package="com.example.repositories"/>

Or in your @Configuration (which will change to a nicer way soon, tacked to @EnableNeo4jRepositories):

@Configuration
@EnableNeo4jRepositories(basePackage="com.example.repositories")
static class TestConfig extends Neo4jConfiguration {
TestConfig() {
setBasePackage("com.example.domain");
}

Looking forward to your feedback,

Nicki and Michael

If you are interested, you can also check out our presentation at GraphConnect that discussed the intermediary state of this work:

Object Graph Mapping with Spring Data Neo4j 3 – Nicki Watt & Michael Hunger @ GraphConnect London 2013 from Neo Technology on Vimeo.




Want to learn more about graph databases? Click below to get your free copy of O’Reilly’s Graph Databases ebook and discover how to use graph technologies for your application today.

Download My Ebook