使用的版本:spring-data-neo4j 4.2.0-BUILD-SNAPSHOT / neo4j-ogm 2.0.6-SNAPSHOT
我有问题才能正确获取关系实体。
以下提取调用不会返回一致的结果(在同一事务中执行):
重要提示:当所有操作(创建,获取)都在同一个事务中完成时,它似乎没问题。
我已经能够通过使用session.query(String,Map)查询关系实体并将其自己映射到我的POJO 来实现解决方法。< / p>
@NodeEntity
public class A {
public A () {}
public A (String name) {
this.name = name;
}
@GraphId
private Long graphId;
private String name;
@Relationship(type="HAS_B", direction=Relationship.OUTGOING)
private B b;
}
@RelationshipEntity(type="HAS_B")
public class B {
public B () {}
public B (String name, A a, C c) {
this.name = name;
this.a = a;
this.c = c;
}
@GraphId
private Long graphId;
@StartNode
private A a;
@EndNode
private C c;
private String name;
}
@NodeEntity
public class C {
public C () {}
public C (String name) {
this.name = name;
}
@GraphId
private Long graphId;
private String name;
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes={MyTest.TestConfiguration.class})
public class MyTest {
@Autowired
private MyBean myBean;
@Configuration
@EnableAutoConfiguration
@EnableTransactionManagement
@EnableNeo4jRepositories("com.nagra.ml.sp.cpm.core.repositories")
public static class TestConfiguration {
@Bean
public org.neo4j.ogm.config.Configuration configuration() {
org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration();
config.driverConfiguration().setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver");
return config;
}
@Bean
public SessionFactory sessionFactory() {
return new SessionFactory(configuration(), "com.nagra.ml.sp.cpm.model");
}
@Bean
public Neo4jTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
@Bean
public MyBean myBean() {
return new MyBean();
}
}
@Test
public void alwaysFails() {
myBean.delete();
myBean.create("1");
try { Thread.sleep(2000); } catch (InterruptedException e) {} //useless
myBean.check("1"); // FAILS HERE !
}
@Test
public void ok() {
myBean.delete();
myBean.createAndCheck("2");
}
}
@Transactional(propagation = Propagation.REQUIRED)
public class MyBean {
@Autowired
private Session neo4jSession;
public void delete() {
neo4jSession.query("MATCH (n) DETACH DELETE n", new HashMap<>());
}
public void create(String suffix) {
C c = new C("c"+suffix);
neo4jSession.save(c);
A a = new A("a"+suffix);
neo4jSession.save(a);
B bRel = new B("b"+suffix, a, c);
neo4jSession.save(bRel);
}
public void check(String suffix) {
//neo4jSession.clear(); //Not working even with this
Number countBRels = (Number) neo4jSession.query("MATCH (:A)-[b:HAS_B]-(:C) WHERE b.name = 'b"+suffix+"' RETURN count(b) as count", new HashMap<>()).iterator().next().get("count");
assertEquals(1, countBRels.intValue()); // OK
Iterable<B> bRels = neo4jSession.query(B.class, "MATCH (:A)-[b:HAS_B]-(:C) WHERE b.name = 'b"+suffix+"' RETURN b", new HashMap<>());
boolean relationshipFound = bRels.iterator().hasNext();
assertTrue(relationshipFound); // FAILS HERE !
}
public void createAndCheck(String suffix) {
create(suffix);
check(suffix);
}
}
答案 0 :(得分:4)
此查询session.query(B.class, "MATCH (:A)-[b:HAS_B]-(:C) RETURN b")
仅返回关系,但不返回起始节点或结束节点,因此OGM无法对此进行补充。您需要始终返回开始和结束节点以及session.query(B.class, "MATCH (a:A)-[b:HAS_B]-(c:C) RETURN a,b,c")
当您在同一事务中创建和获取数据时,它似乎有效的原因是会话已经有a
和c
的缓存副本,因此b
可以是用缓存的开始和结束节点加水。
答案 1 :(得分:0)
首先,请从OGM 2.0.6-SNAPSHOT升级到2.1.0-SNAPSHOT。我注意到前者的一些违规行为可能是问题的一部分。
现在进行测试。这里有几件事情值得研究。
@DirtiesContext
:您似乎无法触及上下文,如果您正在使用它来重置测试之间的上下文,那么您将获得一个新的会话/交易然后关于它是错误的方式。只需使用@Transactional
代替。 Spring JUnit运行器将以特殊方式对待它(参见下一点)。@Commit
it。可以看到如何设置测试的一个很好的示例here。如果你解决这些问题,一切都应该没问题。