0

我正在关注 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)
4

2 回答 2

1

您是否打算建模MyObject以包含单个传出关系类型CONNECTION和单个传入关系类型CONNECTION,其中每个关系都有一个属性name

示例子图

因此,如果我们正在查看EndObject,那么startConnection是与 name的关系还是与 nameconn2endConnection关系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由无效的关系实体表示。

删除初始化,它应该可以按预期工作。

于 2015-08-06T03:43:32.167 回答
0

感谢 Luanne 的回答/建议。我偶然发现了您的优秀文章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;
    }
}

而且效果很好。我还将尝试您删除无效初始化的其他建议。

再次感谢,

马诺伊。

于 2015-08-13T13:06:40.493 回答