Spring data neo4j (4.1) 关系实体的一致性和映射问题
Spring data neo4j (4.1) consistency and mapping problems with relationship entities
我将 SDN 4.1.2 与 neo4j 3.0.4 一起使用,我发现了我在简单代码片段中总结的奇怪行为(将 HttpDriver 与远程数据库结合使用)。
我有 2 个问题(详见下文):
- 存储库 count() 方法returns 对关系实体的错误计数
- 存储库 findOne() 方法不返回最新映射
型号类:
@NodeEntity
public class A {
@GraphId
private Long graphId;
@Relationship(type="HAS_B", direction = Relationship.OUTGOING)
private Set<B> bSet = new HashSet<>();
public Long getGraphId() {
return graphId;
}
public Set<B> getBSet() {
return bSet;
}
}
@RelationshipEntity(type="HAS_B")
public class B {
@GraphId
private Long graphId;
private String value;
@StartNode
private A a;
@EndNode
private C c;
public B() {
}
public B(A a, C c, String value) {
this.a = a;
this.c = c;
this.value = value;
}
}
@NodeEntity
public class C {
@GraphId
private Long graphId;
}
问题 1:
// Create C node
C c = new C();
c = cRepository.save(c);
// Create A node
A a = new A();
a = aRepository.save(a);
assertEquals(0, a.getBSet().size());
// Create B relationships from A to C (relationship entities)
B b1 = new B(a, c, "value1");
B b2 = new B(a, c, "value2");
b1 = bRepository.save(b1);
b2 = bRepository.save(b2);
//assertEquals(2, bRepository.count()); // returns 0 instead of 2 !!
最后一行:存储库计数 returns 0 而不是 2 !
问题 2:
// Create C node
C c = new C();
c = cRepository.save(c);
// Create A node
A a = new A();
a = aRepository.save(a);
assertEquals(0, a.getBSet().size());
// Create B relationships from A to C (relationship entities)
B b1 = new B(a, c, "value1");
B b2 = new B(a, c, "value2");
b1 = bRepository.save(b1);
b2 = bRepository.save(b2);
// Reload a
a = aRepository.findOne(a.getGraphId(), -1);
assertEquals(2, a.getBSet().size());
// Delete b1
bRepository.delete(b1);
// This is not working (deleted in DB, but still present in POJO when fetched again below)
//neo4jOperations.query("MATCH (a:A)-[b1:HAS_B]-(c:C) WHERE b1.value = 'value1' DELETE b1", new HashMap());
// Reload a
a = aRepository.findOne(a.getGraphId(), -1);
assertEquals(1, a.getBSet().size());
如果关系删除是使用 CYPHER 查询而不是存储库删除操作完成的,当通过存储库重新加载对象时,删除的关系仍然存在出现在 POJO 中(最后一个断言失败,大小 == 2 而不是 1)。但是我可以看到关系已经在数据库中被正确删除了。
我尝试使用会话范围 (@Scope(value = "session", proxyMode = ScopedProxyMode.xxx) 但它没有帮助。在文档中,明确地说 SDN/OGM 没有缓存 ,但我不明白这种行为。
提前感谢您告诉我我做错了什么或者是错误。
第一个问题是依赖关系实体的错误。请在此处记录问题 https://jira.spring.io/browse/DATAGRAPH
第二个不是——会话不知道在自定义 Cypher 查询中发生了什么,并且在同一会话中重新加载实体只会产生扩展子图(如果适用)的效果。不幸的是,这在 4.1.x 中没有得到足够好的记录。 4.2.x 的文档在这里得到了很大改进:http://docs.spring.io/spring-data/neo4j/docs/4.2.x/reference/html/#_design_consideration_session_caching
最重要的是,如果您使用自定义密码查询来修改实体的状态,那么您必须获得一个新会话以从基础图形中重新加载它们。
我将 SDN 4.1.2 与 neo4j 3.0.4 一起使用,我发现了我在简单代码片段中总结的奇怪行为(将 HttpDriver 与远程数据库结合使用)。
我有 2 个问题(详见下文):
- 存储库 count() 方法returns 对关系实体的错误计数
- 存储库 findOne() 方法不返回最新映射
型号类:
@NodeEntity
public class A {
@GraphId
private Long graphId;
@Relationship(type="HAS_B", direction = Relationship.OUTGOING)
private Set<B> bSet = new HashSet<>();
public Long getGraphId() {
return graphId;
}
public Set<B> getBSet() {
return bSet;
}
}
@RelationshipEntity(type="HAS_B")
public class B {
@GraphId
private Long graphId;
private String value;
@StartNode
private A a;
@EndNode
private C c;
public B() {
}
public B(A a, C c, String value) {
this.a = a;
this.c = c;
this.value = value;
}
}
@NodeEntity
public class C {
@GraphId
private Long graphId;
}
问题 1:
// Create C node
C c = new C();
c = cRepository.save(c);
// Create A node
A a = new A();
a = aRepository.save(a);
assertEquals(0, a.getBSet().size());
// Create B relationships from A to C (relationship entities)
B b1 = new B(a, c, "value1");
B b2 = new B(a, c, "value2");
b1 = bRepository.save(b1);
b2 = bRepository.save(b2);
//assertEquals(2, bRepository.count()); // returns 0 instead of 2 !!
最后一行:存储库计数 returns 0 而不是 2 !
问题 2:
// Create C node
C c = new C();
c = cRepository.save(c);
// Create A node
A a = new A();
a = aRepository.save(a);
assertEquals(0, a.getBSet().size());
// Create B relationships from A to C (relationship entities)
B b1 = new B(a, c, "value1");
B b2 = new B(a, c, "value2");
b1 = bRepository.save(b1);
b2 = bRepository.save(b2);
// Reload a
a = aRepository.findOne(a.getGraphId(), -1);
assertEquals(2, a.getBSet().size());
// Delete b1
bRepository.delete(b1);
// This is not working (deleted in DB, but still present in POJO when fetched again below)
//neo4jOperations.query("MATCH (a:A)-[b1:HAS_B]-(c:C) WHERE b1.value = 'value1' DELETE b1", new HashMap());
// Reload a
a = aRepository.findOne(a.getGraphId(), -1);
assertEquals(1, a.getBSet().size());
如果关系删除是使用 CYPHER 查询而不是存储库删除操作完成的,当通过存储库重新加载对象时,删除的关系仍然存在出现在 POJO 中(最后一个断言失败,大小 == 2 而不是 1)。但是我可以看到关系已经在数据库中被正确删除了。
我尝试使用会话范围 (@Scope(value = "session", proxyMode = ScopedProxyMode.xxx) 但它没有帮助。在文档中,明确地说 SDN/OGM 没有缓存 ,但我不明白这种行为。
提前感谢您告诉我我做错了什么或者是错误。
第一个问题是依赖关系实体的错误。请在此处记录问题 https://jira.spring.io/browse/DATAGRAPH
第二个不是——会话不知道在自定义 Cypher 查询中发生了什么,并且在同一会话中重新加载实体只会产生扩展子图(如果适用)的效果。不幸的是,这在 4.1.x 中没有得到足够好的记录。 4.2.x 的文档在这里得到了很大改进:http://docs.spring.io/spring-data/neo4j/docs/4.2.x/reference/html/#_design_consideration_session_caching
最重要的是,如果您使用自定义密码查询来修改实体的状态,那么您必须获得一个新会话以从基础图形中重新加载它们。