刚刚将Spring Data Neo4j 3项目迁移到版本4(4.0.0.RELEASE,Neo4j 2.2.5社区服务器),并遇到了一个简单的单向对象关系没有按预期更新的问题。这种关系不使用RelationshipEntity。
节点A,B1和B2已经存在于数据存储区中,并且存在关系A - > B1,将A的B目标节点改变为B2并且保存A给出B1< -A-> B2。创建了新关系,但未删除与B1的旧关系。
expected resulting state :: actual resulting state
A定义了与B的关系,但B没有定义与A的关系(因为B到A可能最终只有一个到太多)。
...imports omitted
@NodeEntity
public class TypeA {
@GraphId
private Long id;
@Relationship(type = "TYPEB", direction = Relationship.OUTGOING)
private TypeB b;
...getters and setters omitted
}
和B
...imports omitted
@NodeEntity
public class TypeB {
@GraphId
private Long id;
private String identifier;
public TypeB() {}
public TypeB(String identifier) {
this.identifier = identifier;
}
...getters and setters omitted
}
调试它需要很长时间(尽管应用程序中存在一致的失败),因为似乎无法编写失败的集成测试(针对真正的Neo4j服务器运行)。实际上,当在测试运行时创建对象A,B1和B2时,我无法编写失败的测试。但是,当运行测试时(运行应用程序时的实际情况)三个节点和关系已经存在于数据存储区中,则B1< -A - >可以看到B2的结果。测试的基本结构如下(可提供完整的代码)。
// Find the TypeA node
Iterable<TypeA> As = typeARepository.findAll();
TypeA a = Iterables.get(As, 0);
// Find the TypeB node using its String identifier
TypeB b1 = typeBRepository.findByIdentifier(ONE);
assertNotNull(b1);
assertEquals(ONE, b1.getIdentifier());
// check that this is the TypeB node that is related to a
assertEquals(b1.getId(), a.getB().getId());
// Find the other TypeB node using its String identifier
TypeB b2 = typeBRepository.findByIdentifier(TWO);
assertNotNull(b2);
assertEquals(TWO, b2.getIdentifier());
// now create a relationship between a and this TypeB node instead
a.setB(b2);
// and save a
TypeA savedUpdatedA = typeARepository.save(a);
在测试运行时以编程方式创建存储库。并使用GraphAware RestTest库在运行存储库保存调用之前和之后验证数据存储子图。
设置:
<logger name="org.neo4j.ogm" level="DEBUG" />
可以看出,发送到Neo4j服务器的Cypher不包括对起始A - >的删除调用。当节点已存在于数据存储区中时保存a的B1关系。它在测试运行时创建节点时执行。所以我认为在Neo4jSession周围存在一个问题,即现有的关系没有被标记为删除 - 但是当使用相同的会话来创建对象时(在测试中)。
是否有人在使用或迁移到SDN 4时遇到类似问题?我记不起用SDN 3看到的了。这不是我看起来很努力的东西,它似乎很有用,但显然SDN 4是完全重写的。
答案 0 :(得分:0)
我相信现在已经修复了。您需要使用OGM的最新快照版本1.1.4-SNAPSHOT,而不是1.1.3版本。