Migrating Spring Data Neo4j 3.x to 4.0 - Indices, Fetching, and Conclusion

DZone 's Guide to

Migrating Spring Data Neo4j 3.x to 4.0 - Indices, Fetching, and Conclusion

Let's conclude this series of migrating Spring Data Neo4j from version 3.x to 4.0 by highlighting some important differences in terms of indexing via SDN.

· Database Zone ·
Free Resource

There are two types of people in this world: Those that say the plural of "index" is "indices", and those who say it is "indexes".  But this post isn't about such a debate (although...).

(Also of note: There are actually 10 types of people in this world: Those that understand binary, and those that don't.)

Image title


Irrespective of your thoughts on syntax and lexicography, we will conclude this series of migrating Spring Data Neo4j from version 3.x to 4.0 by highlighting some important differences in terms of indexing via SDN.  After that, I will quickly discuss something I had left out of a previous post related to lazy loading.


Indexing is a key concern for any developer or DBA, so it is important to know how your particular persistence store operates in that respect; and, while covering indexing in Neo4j in depth is outside of the scope of this article, I suggest going here and here to read more on indexing in Neo4j.

Previously in SDN, we would make use of the @Indexed annotation for both schema indices (e.g. indexing the "username" property of a "Person" node/class) and legacy indices (e.g. Lucene-based FULLTEXT indices).

Using Indices

As of SDN 4.0, the @Indexed annotation is no longer supported.  Spring Data Neo4j will automatically use any schema indices that are in place.  In order to make use of legacy indices, we must use the START clause in Cypher queries.  Note that auto indices are also accessible via query methods within templates and repositories.

Managing Indices

One serious departure from previous versions of SDN is a change in philosophy when it comes to maintaining indices, namely that, "index maintenance should not be part of your application code. For that reason, it does not provide any explicit index-related functionality."

So, you are going to have roll your own code as far as creating, updating, and deleting indices go.

Fortunately, when dealing with schema indices, simple Cypher commands can be used to create/delete such things, and Neo4j automatically adds/removes nodes from the indices as needed.

When it comes to legacy indices, things are a bit more complicated.

For full-text and spatial indices, we can consider the following.

From the SDN documentation:

"To create fulltext entries for an entity you can add the updated nodes within AfterSaveEvents to a remote fulltext-index via Neo4j’s REST API. If you use the DefaultRequest used by the OGM, then authentication will be taken care of as well."

An example, also from the SDN docs:

final CloseableHttpClient httpClient = HttpClients.createDefault();

ApplicationListener<AfterSaveEvent> afterSaveEventApplicationListener() {
    return new ApplicationListener<AfterSaveEvent>() {
        public void onApplicationEvent(AfterSaveEvent event) {
            Neo4jRequest<String> neo4jRequest = new DefaultRequest(httpClient);
            if(event.getEntity() instanceof Person) {
                Person person = (Person) event.getEntity();
                //Construct the JSON statements

In either case, if you feel like going outside of the SDN framework, you can always utilize Neo4j' REST APIs to manage indices.

A Note on @Fetch

It is no longer supported or needed!

Image title

Not THAT kind!

(Courtesy: andreaarden.com)

As you have likely already figured out, owing to SDN 4's implementation, lazy loading and fetching is handled through the use of configurable sessions that allow fetch depths to be set.  With this kind of intelligent behavior, @Fetch has gone away!  Woohoo!

Tying up Loose Ends

Throughout this series, we have examined some of the many changes and improvements that have happened with the release of Spring Data Neo4j 4.0.  As you use the framework more, you will doubtlessly encounter performance improvements and other conveniences that will go a long way to improving your productivity with Neo4j in a Spring-based environment.

Migrating versions—especially major ones—always poses some challenges, but the path taken here is one that is very straight forward.

That said, it is definitely worthwhile going over the Spring Data Neo4j documentation (found here) to see what else is in store for you.  Of particular note, have a close look at the detailed Migration Guide that has been provided.


Integrating Neo4j in both enterprise and non-enterprise environments via Spring has never been easier.  The performance concerns that existed with prior versions of Spring Data Neo4j have largely been addressed in an effective manner.  The previously-chatty SDN has been quieted to a targeted, focused stream that has improved efficiency when communciating with Neo4j over the wire.

We have covered topics ranging from the underlying differences of this latest version of SDN, to the new concepts it introduces, to how graph entities and indices are handled.  This series is meant to be an introduction into migrating from 3.x to 4.0 (as the title has so obviously reminded you), and so spend the time to dig in a bit deeper into the documentation that exists.

If you are like me and have been using Spring Data Neo4j for some time now, you will definitely welcome the changes put forth, as well as the thought and effort put into making the transition from SDN 3.x to 4.0 a direct one.  Taking Von Neumann's Store and making it work with the latest SDN version honestly took less than a couple hours!

So, go have a look at the new Spring Data Neo4j and dive right in!  Explore the features and get familiar with what is available.

Thank you for following this series and I hope you have found it useful!  Happy graphing!

(Merry Graphmas?)

Image title

Still not a graph.

databases ,java ,migration ,neo4j ,spring ,spring data neo4j

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}