Spring 数据 Neo4j 5 OGM 3 和 Spring 启动 2.0.0.M4

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

我正在尝试从 SDN 4.2 迁移到 SDN 5OGM 3

除一种情况外,一切几乎都完美无缺。

现在为了保存实体,我必须使用 depth=2 而不是像 SDN 4.2 那样的 depth=1

那里很难解释,所以我在 GitHub 创建了一个演示项目来重现这个问题 - https://github.com/Artgit/spring-boot-2.0.0.M4-sdn5-ogm3-saving-issue

重现步骤:

如果您想使用自己的 Neo4j 实例,请跳过第 1 步并从第 2 步开始阅读。

  1. 运行 mvn docker:start -Dfile.encoding=UTF-8 以便在 Docker 容器中启动 Neo4j 3.2.5(必须安装 Docker)

  2. 执行测试com.decisionwanted.domain.DecisionCharacteristicIT.testUpdateValue()

测试应该失败,断言:

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 

从下面的代码可以看出:

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

assertEquals(user3, rdbmsHorScalingValue.getUpdateUser());

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

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

我已经用 user3 更新了 rdbmsHorScalingValue 并且在通过 id 获得 Value 之后(valueDao.getById()) 我希望这个用户是 rdbmsHorScalingValue.getUpdateUser() 但由于某些未知原因,它不是是的。

但是如果我们改变以下方法:com.decisionwanted.domain.dao.decision.characteristic.value.history.HistoryValueDaoImpl.create(Value) 将深度从 1 保存到 2 - 一切开始正常工作。

现在我不知道问题出在哪里,我唯一知道的是 - 它在 SDN 4.2 中保存深度 = 1 时工作正常。

请告诉我问题出在哪里(为什么它不适用于 SDN 5)以及如何解决。

问题出在您的更新方法 (com.decisionwanted.domain.dao.decision.characteristic.value.ValueDaoImpl#update)

您正在更改关系 (UPDATED_BY),该关系未在当前会话中跟踪(绑定到事务)。它会离开你的旧 UPDATED_BY 关系——你最终有 2 个关系——直接在 Neo4j 中检查你的图表。这种情况下的行为是未定义的,OGM 期望图形模型与对象模型匹配。

为什么它适用于保存深度 2 - 保存会将值实例和与用户的关系添加到会话中(对于深度 1,它只会对值实例而不是关系执行此操作)以及随后的更改然后检测到

你应该在更新方法的开始加载值实例(直到你修改的深度):

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

如果您使用来自 @Transactional 服务的 ValueDao 对象,您不需要它,但 *IT 测试本身应该是事务性的以反映这一点。