【发布时间】:2017-02-12 08:47:29
【问题描述】:
使用的版本:spring-data-neo4j 4.2.0-BUILD-SNAPSHOT / neo4j-ogm 2.0.6-SNAPSHOT
我有正确获取关系实体的问题。
以下 fetch 调用不会返回一致的结果(在同一事务中执行):
- session.query("MATCH (:A)-[b:HAS_B]-(:C) RETURN count(b) as count") 返回 1
- session.query("MATCH (:A)-[b:HAS_B]-(:C) RETURN b") 正确返回关系实体作为RelationshipModel对象
- session.query(B.class, "MATCH (:A)-[b:HAS_B]-(:C) RETURN b") 返回空值!
重要说明:当所有操作(create、fetch)都在同一个事务中完成时,似乎没问题。
我已经能够实现一种解决方法,方法是使用 session.query(String, Map) 来查询关系实体并自己将其映射到我的 POJO。
@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);
}
}
【问题讨论】:
-
只是确认:其他事务是否已提交?
-
是的,根据 Neo4jTransactionManager 日志,前 2 个事务已正确提交(对于 delete() 和 create() 调用)。由于断言异常,第三个事务(用于 check())被回滚。而且我还可以在日志中看到为每个事务创建了一个新会话(“为 Neo4j OGM 事务打开了新会话 [org.neo4j.ogm.session.Neo4jSession@xxxx]”)
-
哪些方法?我尝试用@Transactional 标记MyBean 中的方法,但它并没有解决问题。
-
如果我也将我的测试方法 (alwaysFails()) 标记为 Transactional,它可以正常工作,因为一切都在同一个事务中完成。
-
是的,我尝试将 @Transactional 放在 createAndCheck() (以及此类的所有其他方法)上,但效果不佳。 createAndCheck() 没有问题,就是我直接调用create() 再调用check() 出现问题。
标签: spring neo4j spring-data-neo4j-4 neo4j-ogm