Search code examples
neo4jspring-data-neo4jspring-data-neo4j-4neo4j-ogmspring-data-neo4j-5

Spring Data Neo4j 5 OGM 3 and Spring Boot 2.0.0.M4


I'm trying to migrate from SDN 4.2 to SDN 5 and OGM 3

Everything almost works perfectly except one case.

Right now in order to save the entity I have to use depth=2 instead of depth=1 like at SDN 4.2

It's hard to explain there so I have created a demo project at GitHub that reproduces this issue - https://github.com/Artgit/spring-boot-2.0.0.M4-sdn5-ogm3-saving-issue

Steps to reproduce:

If you want to use your own Neo4j instance please skip step #1 and start reading from step #2.

  1. Run mvn docker:start -Dfile.encoding=UTF-8 in order to spin up Neo4j 3.2.5 in Docker container (Docker must be installed)

  2. Execute test com.decisionwanted.domain.DecisionCharacteristicIT.testUpdateValue()

The test should fail with the assertion:

java.lang.AssertionError: expected:<BaseEntity [id=3, class=class com.decisionwanted.domain.model.user.User, createDate=Wed Oct 04 21:54:17 EEST 2017, updateDate=Wed Oct 04 21:54:17 EEST 2017]> but was:<BaseEntity [id=2, class=class com.decisionwanted.domain.model.user.User, createDate=Wed 

As you can see from the following code:

rdbmsHorScalingValue = valueDao.update(rdbmsHorScalingValue, newStringValue2, newStringDescription2, user3,
                null);

assertEquals(user3, rdbmsHorScalingValue.getUpdateUser());

rdbmsHorScalingValue = valueDao.getById(rdbmsHorScalingValue.getId());

assertEquals(user3, rdbmsHorScalingValue.getUpdateUser()); // Error here !!!!

I have updated rdbmsHorScalingValue with user3 and after getting Value by id (valueDao.getById()) I expect this user as rdbmsHorScalingValue.getUpdateUser() but for some unknown reason, it is not true.

But if we change at the following method: com.decisionwanted.domain.dao.decision.characteristic.value.history.HistoryValueDaoImpl.create(Value) saving depth from 1 to 2 - everything starts working fine.

Right now I don't know where is the issue and the only thing I know - it is working fine with saving depth = 1 with SDN 4.2.

Please tell me where is the issue(why it doesn't work with SDN 5) and how to solve it.


Solution

  • The issue is with you update method (com.decisionwanted.domain.dao.decision.characteristic.value.ValueDaoImpl#update)

    You are changing a relationship (UPDATED_BY), which is not tracked in a current session (which is bound to a transaction). It will leave your old UPDATED_BY relationship - you end up with 2 relationships - check your graph in Neo4j directly. Behaviour for such case is undefined, OGM expects the graph model to mach the object model.

    Why it works with saving depth 2 - the save will add the Value instance and the relationship to user into the session (with depth 1 it will do that only for the Value instance, not the relationship) and the subsequent change is then detected

    You should load the value instance at the beginning of the update method (up to the depth you modify):

    value = valueRepository.getById(value.getId());
    

    If you use the ValueDao objects from @Transactional services you don't need that, but the *IT tests should themselves be transactional to reflect that.