我正在关注 - http://neo4j.com/docs/ogm/java/stable/
的Neo4j OGM指南对于Relationship实体,我们需要一个起始节点和一个结束节点。我稍微修改了一下这个例子(为了让它更简单) -
@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的缺点?
提前致谢,
的Manoj。
尝试Luanne的建议后更新 -
谢谢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)
答案 0 :(得分:1)
您是否打算将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
。实际上,curl -XPUT localhost:9200/test/_mapping/test -d '{
"test": {
"properties": {
"keyword": {
"type": "string",
"index": "not_analyzed"
},
"items": {
"type": "nested",
"properties": {
"name": {
"type": "string"
},
"item_property_1": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}'
由无效关系实体表示。
删除初始化,它应该按预期工作。
答案 1 :(得分:0)
感谢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;
}
}
它完美无缺。我还将尝试删除无效初始化的其他建议。
再次感谢,
的Manoj。