当 StartNode 和 EndNode 是同一类型的对象时,Neo4j OGM RelationshipEntity
Neo4j OGM RelationshipEntity when StartNode and EndNode are objects of same type
我正在关注 Neo4j OGM 指南 - http://neo4j.com/docs/ogm/java/stable/
对于关系实体,我们需要有一个开始节点和一个结束节点。我稍微修改了这个例子(让它像这样更简单)-
@NodeEntity
public class Student extends Entity {
private String name;
@Relationship(type= "ENROLLED")
private Enrollment enrollment = new Enrollment();
public String getName() {
return name;
}
public Enrollment getEnrollment() {
return enrollment;
}
public void setEnrollment(Enrollment enrollment) {
this.enrollment = enrollment;
}
public Student() {
}
public Student(String name) {
this.name = name;
}
}
@NodeEntity
public class Course extends Entity {
private String name;
public String getName() {
return name;
}
@Relationship(type= "ENROLLED", direction= Relationship.INCOMING)
private Enrollment enrollment = new Enrollment();
public Enrollment getEnrollment() {
return enrollment;
}
public void setEnrollment(Enrollment enrollment) {
this.enrollment = enrollment;
}
public Course() {
}
public Course(String name) {
this.name = name;
}
}
@RelationshipEntity(type = "ENROLLED")
public class Enrollment extends Entity {
@StartNode
private Student student;
@EndNode
private Course course;
private Date enrolledDate;
public Student getStudent() {
return student;
}
public Course getCourse() {
return course;
}
public Date getEnrolledDate() {
return enrolledDate;
}
public Enrollment() {
}
public Enrollment(Student student, Course course, Date enrolledDate) {
this.student = student;
this.course = course;
this.enrolledDate = enrolledDate;
}
}
现在,当我尝试在 Neo4j 中保存它时,它工作正常。但是在我的场景中,StartNode 和 EndNode 对象的类型是相同的 -
@NodeEntity
public class MyObject extends Entity {
private String name;
@Relationship(type="CONNECTION")
private MyConnection startConnection = new MyConnection();
@Relationship(type="CONNECTION", direction= Relationship.INCOMING)
private MyConnection endConnection = new MyConnection();
public String getName() {
return name;
}
public MyConnection getStartConnection() {
return startConnection;
}
public void setStartConnection(MyConnection myConnection) {
this.startConnection = myConnection;
}
public MyConnection getEndConnection() {
return endConnection;
}
public void setEndConnection(MyConnection endConnection) {
this.endConnection = endConnection;
}
public MyObject() {
super();
}
public MyObject(String name) {
super();
this.name = name;
}
}
@RelationshipEntity(type="CONNECTION")
public class MyConnection extends Entity {
@StartNode
private MyObject start;
@EndNode
private MyObject end;
private String name;
public String getName() {
return name;
}
public MyConnection() {
super();
}
public MyConnection(MyObject start, MyObject end, String name) {
super();
this.start = start;
this.end = end;
this.name = name;
}
}
当我尝试使用 -
保存这些内容时
public class Main {
public static void main(String[] args) {
Session session = Neo4jSessionFactory.getInstance().getNeo4jSession();
Student s = new Student("manoj");
Course c = new Course("physics");
Enrollment e = new Enrollment(s, c, new Date());
s.setEnrollment(e);
c.setEnrollment(e);
MyObject startObj = new MyObject("Start Object");
MyObject endObj = new MyObject("End Object");
MyConnection conn = new MyConnection(startObj, endObj, "Connection");
startObj.setStartConnection(conn);
endObj.setEndConnection(conn);
try(Transaction tx = session.beginTransaction()) {
session.save(s);
session.save(c);
session.save(e);
session.save(startObj);
session.save(endObj);
session.save(conn);
tx.commit();
}
}
}
学生、课程和注册对象被保存,但是两个 MyObject 和 MyConnection 对象没有被保存,我得到以下异常 -
Exception in thread "main" java.lang.NullPointerException
at org.neo4j.ogm.metadata.MetaData.classInfo(MetaData.java:76)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelationshipEntity(EntityGraphMapper.java:389)
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:319)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:262)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:154)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelatedEntity(EntityGraphMapper.java:528)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelationshipEntity(EntityGraphMapper.java:420)
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:319)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:262)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:154)
at org.neo4j.ogm.mapper.EntityGraphMapper.map(EntityGraphMapper.java:87)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:65)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:41)
at org.neo4j.ogm.session.Neo4jSession.save(Neo4jSession.java:370)
at neo4j.ogm.ex.Main.main(Main.java:37)
你能帮我解决这个问题吗 -
1) StartNode 和 EndNode 对象是否必须是不同类型的?
2) 我的代码有问题还是 Neo4j OGM 的缺点?
提前致谢,
马诺杰。
尝试 Luanne 的建议后更新 -
谢谢卢安妮。我尝试了你的建议,尽管我不得不以不同的方式指定 URL。我用了 -
http://m2.neo4j.org/content/repositories/snapshots
因为默认情况下它使用 https 并且我遇到了一些安全异常并且没有下载此依赖项。
无论如何,使用 1.1.1-SNAPSHOT 版本,我仍然得到以下错误 -
Exception in thread "main" java.lang.NullPointerException
at org.neo4j.ogm.metadata.MetaData.classInfo(MetaData.java:80)
at org.neo4j.ogm.mapper.EntityGraphMapper.haveRelationEndsChanged(EntityGraphMapper.java:391)
at org.neo4j.ogm.mapper.EntityGraphMapper.getRelationshipBuilder(EntityGraphMapper.java:362)
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:325)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:276)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:157)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelatedEntity(EntityGraphMapper.java:571)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelationshipEntity(EntityGraphMapper.java:473)
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:329)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:276)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:157)
at org.neo4j.ogm.mapper.EntityGraphMapper.map(EntityGraphMapper.java:90)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:67)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:43)
at org.neo4j.ogm.session.Neo4jSession.save(Neo4jSession.java:376)
at neo4j.ogm.ex.Main.main(Main.java:37)
您是否打算将 MyObject
建模为包含单个传出关系类型 CONNECTION
和单个传入关系类型 CONNECTION
,其中每个关系都有一个 属性 name
?
因此,如果我们查看 EndObject
,那么 startConnection
是与名称 conn2
的关系,而 endConnection
是与名称 conn1
的关系?
如果是这样,我们这里可能有问题。 https://jira.spring.io/browse/DATAGRAPH-728
更新:
这毕竟不是错误。问题是你在 MyObject
:
中的初始化
@Relationship(type="CONNECTION")
private MyConnection startConnection = new MyConnection();
@Relationship(type="CONNECTION", direction= Relationship.INCOMING)
private MyConnection endConnection = new MyConnection();
您已将 startConnection
和 endConnection
初始化为一个无效的关系实体,即没有开始和结束节点的实体。
在您的测试中,您将 startConnection
设置为 startObj
而不是结束。实际上,endConnection
由无效关系实体表示。
删除初始化,它应该会如您所愿地工作。
感谢 Luanne 的回答/建议。我看到了您的优秀文章 The essence of Spring Data Neo4j 4 并意识到我的需求与成分配对示例(在您的文章中提到)非常相似。对我来说,两个对象 (MyObject) 之间可以有一个连接 (MyConnection)。所以我修改后的代码是这样的 -
package neo4j.ogm.ex.domain;
import java.util.HashSet;
import java.util.Set;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
@NodeEntity
public class MyObject extends Entity {
private String name;
@Relationship(type="CONNECTION", direction= Relationship.UNDIRECTED)
private Set<MyConnection> connections = new HashSet<>();
public String getName() {
return name;
}
public Set<MyConnection> getConnections() {
return connections;
}
public void addConnection(MyConnection myConnection) {
myConnection.getStart().getConnections().add(myConnection);
myConnection.getEnd().getConnections().add(myConnection);
}
public MyObject() {
super();
}
public MyObject(String name) {
super();
this.name = name;
}
}
package neo4j.ogm.ex.domain;
import org.neo4j.ogm.annotation.EndNode;
import org.neo4j.ogm.annotation.RelationshipEntity;
import org.neo4j.ogm.annotation.StartNode;
@RelationshipEntity(type="CONNECTION")
public class MyConnection extends Entity {
@StartNode
private MyObject start;
@EndNode
private MyObject end;
private String name;
public String getName() {
return name;
}
public MyObject getStart() {
return start;
}
public MyObject getEnd() {
return end;
}
public MyConnection() {
super();
}
public MyConnection(MyObject start, MyObject end, String name) {
super();
this.start = start;
this.end = end;
this.name = name;
}
}
而且效果很好。我还将尝试您提出的删除无效初始化的其他建议。
再次感谢,
马诺杰。
我正在关注 Neo4j OGM 指南 - http://neo4j.com/docs/ogm/java/stable/
对于关系实体,我们需要有一个开始节点和一个结束节点。我稍微修改了这个例子(让它像这样更简单)-
@NodeEntity
public class Student extends Entity {
private String name;
@Relationship(type= "ENROLLED")
private Enrollment enrollment = new Enrollment();
public String getName() {
return name;
}
public Enrollment getEnrollment() {
return enrollment;
}
public void setEnrollment(Enrollment enrollment) {
this.enrollment = enrollment;
}
public Student() {
}
public Student(String name) {
this.name = name;
}
}
@NodeEntity
public class Course extends Entity {
private String name;
public String getName() {
return name;
}
@Relationship(type= "ENROLLED", direction= Relationship.INCOMING)
private Enrollment enrollment = new Enrollment();
public Enrollment getEnrollment() {
return enrollment;
}
public void setEnrollment(Enrollment enrollment) {
this.enrollment = enrollment;
}
public Course() {
}
public Course(String name) {
this.name = name;
}
}
@RelationshipEntity(type = "ENROLLED")
public class Enrollment extends Entity {
@StartNode
private Student student;
@EndNode
private Course course;
private Date enrolledDate;
public Student getStudent() {
return student;
}
public Course getCourse() {
return course;
}
public Date getEnrolledDate() {
return enrolledDate;
}
public Enrollment() {
}
public Enrollment(Student student, Course course, Date enrolledDate) {
this.student = student;
this.course = course;
this.enrolledDate = enrolledDate;
}
}
现在,当我尝试在 Neo4j 中保存它时,它工作正常。但是在我的场景中,StartNode 和 EndNode 对象的类型是相同的 -
@NodeEntity
public class MyObject extends Entity {
private String name;
@Relationship(type="CONNECTION")
private MyConnection startConnection = new MyConnection();
@Relationship(type="CONNECTION", direction= Relationship.INCOMING)
private MyConnection endConnection = new MyConnection();
public String getName() {
return name;
}
public MyConnection getStartConnection() {
return startConnection;
}
public void setStartConnection(MyConnection myConnection) {
this.startConnection = myConnection;
}
public MyConnection getEndConnection() {
return endConnection;
}
public void setEndConnection(MyConnection endConnection) {
this.endConnection = endConnection;
}
public MyObject() {
super();
}
public MyObject(String name) {
super();
this.name = name;
}
}
@RelationshipEntity(type="CONNECTION")
public class MyConnection extends Entity {
@StartNode
private MyObject start;
@EndNode
private MyObject end;
private String name;
public String getName() {
return name;
}
public MyConnection() {
super();
}
public MyConnection(MyObject start, MyObject end, String name) {
super();
this.start = start;
this.end = end;
this.name = name;
}
}
当我尝试使用 -
保存这些内容时public class Main {
public static void main(String[] args) {
Session session = Neo4jSessionFactory.getInstance().getNeo4jSession();
Student s = new Student("manoj");
Course c = new Course("physics");
Enrollment e = new Enrollment(s, c, new Date());
s.setEnrollment(e);
c.setEnrollment(e);
MyObject startObj = new MyObject("Start Object");
MyObject endObj = new MyObject("End Object");
MyConnection conn = new MyConnection(startObj, endObj, "Connection");
startObj.setStartConnection(conn);
endObj.setEndConnection(conn);
try(Transaction tx = session.beginTransaction()) {
session.save(s);
session.save(c);
session.save(e);
session.save(startObj);
session.save(endObj);
session.save(conn);
tx.commit();
}
}
}
学生、课程和注册对象被保存,但是两个 MyObject 和 MyConnection 对象没有被保存,我得到以下异常 -
Exception in thread "main" java.lang.NullPointerException
at org.neo4j.ogm.metadata.MetaData.classInfo(MetaData.java:76)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelationshipEntity(EntityGraphMapper.java:389)
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:319)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:262)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:154)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelatedEntity(EntityGraphMapper.java:528)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelationshipEntity(EntityGraphMapper.java:420)
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:319)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:262)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:154)
at org.neo4j.ogm.mapper.EntityGraphMapper.map(EntityGraphMapper.java:87)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:65)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:41)
at org.neo4j.ogm.session.Neo4jSession.save(Neo4jSession.java:370)
at neo4j.ogm.ex.Main.main(Main.java:37)
你能帮我解决这个问题吗 - 1) StartNode 和 EndNode 对象是否必须是不同类型的? 2) 我的代码有问题还是 Neo4j OGM 的缺点?
提前致谢,
马诺杰。
尝试 Luanne 的建议后更新 -
谢谢卢安妮。我尝试了你的建议,尽管我不得不以不同的方式指定 URL。我用了 - http://m2.neo4j.org/content/repositories/snapshots 因为默认情况下它使用 https 并且我遇到了一些安全异常并且没有下载此依赖项。
无论如何,使用 1.1.1-SNAPSHOT 版本,我仍然得到以下错误 -
Exception in thread "main" java.lang.NullPointerException
at org.neo4j.ogm.metadata.MetaData.classInfo(MetaData.java:80)
at org.neo4j.ogm.mapper.EntityGraphMapper.haveRelationEndsChanged(EntityGraphMapper.java:391)
at org.neo4j.ogm.mapper.EntityGraphMapper.getRelationshipBuilder(EntityGraphMapper.java:362)
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:325)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:276)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:157)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelatedEntity(EntityGraphMapper.java:571)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapRelationshipEntity(EntityGraphMapper.java:473)
at org.neo4j.ogm.mapper.EntityGraphMapper.link(EntityGraphMapper.java:329)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntityReferences(EntityGraphMapper.java:276)
at org.neo4j.ogm.mapper.EntityGraphMapper.mapEntity(EntityGraphMapper.java:157)
at org.neo4j.ogm.mapper.EntityGraphMapper.map(EntityGraphMapper.java:90)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:67)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:43)
at org.neo4j.ogm.session.Neo4jSession.save(Neo4jSession.java:376)
at neo4j.ogm.ex.Main.main(Main.java:37)
您是否打算将 MyObject
建模为包含单个传出关系类型 CONNECTION
和单个传入关系类型 CONNECTION
,其中每个关系都有一个 属性 name
?
因此,如果我们查看 EndObject
,那么 startConnection
是与名称 conn2
的关系,而 endConnection
是与名称 conn1
的关系?
如果是这样,我们这里可能有问题。 https://jira.spring.io/browse/DATAGRAPH-728
更新:
这毕竟不是错误。问题是你在 MyObject
:
@Relationship(type="CONNECTION")
private MyConnection startConnection = new MyConnection();
@Relationship(type="CONNECTION", direction= Relationship.INCOMING)
private MyConnection endConnection = new MyConnection();
您已将 startConnection
和 endConnection
初始化为一个无效的关系实体,即没有开始和结束节点的实体。
在您的测试中,您将 startConnection
设置为 startObj
而不是结束。实际上,endConnection
由无效关系实体表示。
删除初始化,它应该会如您所愿地工作。
感谢 Luanne 的回答/建议。我看到了您的优秀文章 The essence of Spring Data Neo4j 4 并意识到我的需求与成分配对示例(在您的文章中提到)非常相似。对我来说,两个对象 (MyObject) 之间可以有一个连接 (MyConnection)。所以我修改后的代码是这样的 -
package neo4j.ogm.ex.domain;
import java.util.HashSet;
import java.util.Set;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
@NodeEntity
public class MyObject extends Entity {
private String name;
@Relationship(type="CONNECTION", direction= Relationship.UNDIRECTED)
private Set<MyConnection> connections = new HashSet<>();
public String getName() {
return name;
}
public Set<MyConnection> getConnections() {
return connections;
}
public void addConnection(MyConnection myConnection) {
myConnection.getStart().getConnections().add(myConnection);
myConnection.getEnd().getConnections().add(myConnection);
}
public MyObject() {
super();
}
public MyObject(String name) {
super();
this.name = name;
}
}
package neo4j.ogm.ex.domain;
import org.neo4j.ogm.annotation.EndNode;
import org.neo4j.ogm.annotation.RelationshipEntity;
import org.neo4j.ogm.annotation.StartNode;
@RelationshipEntity(type="CONNECTION")
public class MyConnection extends Entity {
@StartNode
private MyObject start;
@EndNode
private MyObject end;
private String name;
public String getName() {
return name;
}
public MyObject getStart() {
return start;
}
public MyObject getEnd() {
return end;
}
public MyConnection() {
super();
}
public MyConnection(MyObject start, MyObject end, String name) {
super();
this.start = start;
this.end = end;
this.name = name;
}
}
而且效果很好。我还将尝试您提出的删除无效初始化的其他建议。
再次感谢,
马诺杰。