使用Spring Neo4编写一个带有Spring Neo4j的poc时,我遇到了Bolt驱动程序和Http驱动程序之间似乎不一致的行为。基本上在保存2个节点之间的丰富关系后,测试无法在使用Bolt驱动程序时加载它,但是在尝试使用Http驱动程序时,完全相同的测试成功。
可以从github
下载示例项目这是一项非常基本/直接的测试,唯一的先决条件是您需要在启用Bolt连接器的情况下安装Neo4j 3。
正如Andrej所建议,请在下面的代码的相关部分找到:
@NodeEntity(label = "Person")
public class Person {
private Long id;
private String firstname;
private String lastname;
@Relationship(type = "HAS_CONTACT", direction = Relationship.INCOMING)
private Contact contact;
// getters and setters here .........
}
@NodeEntity(label = "BankAccount")
public class BankAccount {
private Long id;
private Integer balance;
@Relationship(type = "HAS_CONTACT")
private List<Contact> contacts = new ArrayList<>();
// getters and setters here .........
}
@RelationshipEntity(type = "HAS_CONTACT")
public class Contact {
public Contact() {
}
public Contact(BankAccount bankAccount, Person person) {
this.bankAccount = bankAccount;
this.person = person;
this.bankAccount.getContacts().add(this);
this.person.setContact(this);
}
private Long id;
@StartNode
private BankAccount bankAccount;
@EndNode
private Person person;
private String email;
private String phoneNumber;
// getters and setters here .........
}
@Repository
public interface ContactRepository extends GraphRepository<Contact> {
@Query("MATCH (a:BankAccount)-[r:HAS_CONTACT]->(:Person) " +
"WHERE ID(a)={accountId} " +
"RETURN r")
Iterable<Contact> findByAccountId(@Param("accountId") Long accountId);
}
保存1个帐户,1个人和1个人之间的联系关系后,下面的查询是失败的:
Iterable<Contact> contacts = contactRepository.findByAccountId(accountId);
// this assertion will Fail for the BOLT driver, however, it will Succeed for the HTTP driver
// if the accountRepository.findOne(accountId) statement is executed before calling
// contactRepository.findByAccountId(accountId) then the test will also succeed for the BOLT driver
assertThat(size(contacts), is(1));
答案 0 :(得分:1)
请参阅以下neo4j小组关于issue:
的回复无法映射关系实体的原因是因为此查询无法使用开始和结束节点:
@Query("MATCH (a:BankAccount)-[r:HAS_CONTACT]->(p:Person) " + "WHERE ID(a)={accountId} " + "RETURN r,") Iterable<Contact> findByAccountId(@Param("accountId") Long accountId);
您需要返回这些节点才能构造有效的节点 关系实体,像这样:
@Query("MATCH (a:BankAccount)-[r:HAS_CONTACT]->(p:Person) " + "WHERE ID(a)={accountId} " + "RETURN r,a,p") Iterable<Contact> findByAccountId(@Param("accountId") Long accountId);
HTTP端点的副作用是允许它传递 无论如何,此端点都会返回开始和结束节点。请参阅 http://graphaware.com/neo4j/2016/04/06/mapping-query-entities-sdn.html 了解更多信息。