The best way to migrate Spring Data.

When I have this list of Persons here, I should only get one Person.” The query, of course, is a bit contrived here. We know we matched Tom Hanks, so why do we expect to list? But you will see there are some behavioral differences when we migrate to Spring Data Neo4j 6. So let me move, and I also will- Let me move to the new one.

Now we migrate to Spring Data Neo4j 6. I’m going to make sure I’m up-to-date, ’cause I might not be. “sdn-migration”. Yeah. So I was not up-to-date. So I did well to do this. And now let’s look at the same two. If I look again at the Person repository and the test. Now we have, we used to have if I look at my scratch file, except my scratch file is gone. Great. Thank you, IntelliJ. Very clever to discard files that I need. But you can see that the test will have changed.

If we look, let’s look at this one first, “findByActedMovieTitle”. We see you’ve got the same result. However, you can see the projection has changed. You can also use classes if you want, but in that case, it’s more indicative to use interfaces, as long as the property matches, right? So the getter of the name. So in that case, you just need an interface, and you can see that when we extract the birth date, birth year, sorry, I keep saying the birth date, but it’s a year, and the “name”, you used to get whatever you want.

Interface, in that case, was actually enough, and that’s something that is fully supported by Spring Data Neo4j 6. So that’s one of the first differences. And then let’s look at our friend, Tom Hanks. And so if we look at the test… So the query has not changed, and we’ll come back to that in a minute. But if we look at the test that uses it, you will see that we had one Person, right, in the assertion, if you remember? We had “hasSize(1)”. Now we’ve got 12. So I’ve not counted, but I guess we have 12 movies in there. Yes. We have 12 movies. 12 records. 12 rows of records.

That’s a big difference, if you don’t- You might see changes. Although the query is the same, the way it’s interpreted now with Spring Data Neo4j 6, and that’s very important, is much closer to what the Role driver does, what the Cypher data model actually is. In a way, I think my colleague, Jennifer Reif coined this. In a way, you can think of Spring Data Neo4j 5/OGM returning results like this nice little visualization here. There is only one Tom Hanks node and there is a list of 12 movies linked to it.

If we look for a list of Persons, we should get only one node. Spring Data Neo4j 6 is much closer to the actual model of Cypher. It will tell you, “No, no. There are 12 Persons, right?” I have 12 rows, so I have 12 Persons. And so you could think, “But isn’t that wasteful? Like, why would we have 12 different instances of the same node?” And so let’s look at the test a little more. Actually what happens, if you look at what’s called the identity hash code, like the hash code of the object, the technical one, you will see that it’s the same instance, referenced 12 times.

Spring Data Neo4j 6 is Spring Data Neo4j 6.0.2, and I believe today we are at 6.0.7, and 6.1 is being released today as well. So this fix has been included for a long time. You will see that there are 12 instances of the same object. Not 12 instances, sorry. 12 repetitions of the same object here. So Spring Data Neo4j 6 is smart enough to not instantiate it 12 times. However, if you want to stick to the behaviors that were from Spring Data Neo4j 5, which is, “I want to have a single person, because there is a single node in the graph,” what you would write instead, and that’s a very common thing to do when you migrate from Spring Neo4j 5 to Spring Data Neo4j 6, is to write this instead.

If you do this, that is, match the person, aggregate the relationships, aggregate the neighbors, then you will get back to the kind of results you got with Spring Data Neo4j 5. So I would really advise you to be wary of these kinds of things. (clears throat) I think is the best way to think about it is, (clears throat) Spring Data Neo4j 5/OGM as the point of view or the graph view of Neo4j Desktop in a way, Spring Data Neo4j 6 as the table view in a way, of a Neo4j Desktop. That’s the best analogy we could come up with. So, thanks Jennifer for that by the way, again, ’cause that’s a really great analogy, I think.

You might end up doing this quite a lot of times when you have custom queries, make sure if you want to hydrate your object properly, aggregate the relationships and queries, else you will end up with repeated stuff. Could be the same instance, so it’s as wasteful as one would think, but you don’t get a list of one person, you would get a list of 12 Persons. So yeah, that’s a common thing to do. That’s a common thing to do when you need to migrate to Spring Data Neo4j 6. So quite a difference of interpretations, in terms of queries, of custom queries. And in a way, Spring Data Neo4j 6 got closer to what you would get with Role driver or what you would get with Neo4j Desktop when you run something.

It’s much closer to the model of Cypher and it’s not trying to be too smart about things. I know it can be a pain to migrate to, but in a way that’s for the better, That’s an improvement. That’s really an improvement that makes things way easier to reason about. And so we have projections, we have projections with interfaces if needed. You can also resort to classes, otherwise… We had a relationship before, so obviously it’s not a relationship entity anymore, it’s a relationship property when you have only the target node. And what else has changed? I don’t think much has changed since. It’s quite similar, otherwise.

It’s not an “@Entity”, it’s “@Node” etc. So I don’t think there is much more that is interesting here. Of course, you’ve got Spring Element Language configuration for parameters, if you want to, with also different syntax. So yeah, you can use “SpEL” for short, Spring Element Language, so we can configure stuff like that. That’s a very short overview of migration issues, but one is- So to recap… I might show you the Reactive stuff, but I don’t know if that’s relevant. That’s something you can do afterward. First, go from imperative to imperative, and then move to Reactive, if you want to. ‘Cause Reactive support is built-in in Spring Data Neo4j 6.

It’s a first-class citizen, so you can use the Reactive variants as much as you. And so to recap, one of the major differences between Spring Data Neo4j 6 and 5/Neo4j-OGM, Spring Data Neo4j 6 doesn’t use OGM at all. So if you try to use “@NodeEntity”, I’m going to come back to the original branch, if you try to use “@NodeEntity” annotations, I mean any OGM annotations, it’s not going to work. It’s not gonna work at all, because Spring Data Neo4j 6 is going to ignore that. Just use Spring Data Neo4j 6 annotations. Although they might share the same name, sometimes they are completely different. Spring Data Neo4j 6 also only supports Bolt.

If you need HTTP, really think hard about why you need it, and why Bolt cannot solve the problem for you. ‘Cause usually when you need a database running, it’s the query language and the protocol to talk to it. If you need something else, you might want to migrate away from that. And if you need to embed, there are some ways to make Spring Data Neo4j 6 work as embedded. But again, that’s something to consider as well. Like, why do you need to be embedded? Is it something you really need or not? And finally, on the feature comparison, so Transport, only Bolt for 6, not HTTP or embedded. But the rest is kind of similar.

You have, of course, Conversion, it supports optimistic locking, you’ve got mapping from nodes to top-level entities, relationships – nope. You have relationship properties, but not entities. That’s something to watch for. You won’t be able to use a repository for that. You might use custom queries with Neo4jTemplate or Neo4j Client. I think I wanted to say something else but I forgot, But yeah. If you need to migrate, take it step-by-step. First, migrate to the latest Spring Data Neo4j 5/OGM, and then migrate from there to Spring Data Neo4j 6. And be wary that Spring Boot, by default, now includes Spring Data Neo4j 6.

Leave a Comment