如何在 Spring Data Graph 中持久保存 Neo4J NodeEntity 之间的关系,而无需调用 persist 两次

发布于 2024-12-14 21:41:11 字数 1904 浏览 0 评论 0原文

如果我删除第一个 persist(),下面的测试就会失败。为什么我需要持久化 NodeEntity 才能实例化 Set?有更好的方法来做到这一点吗?我不想比必要的情况更频繁地写入数据库。

 @Test
public void testCompetenceCreation() {
    Competence competence = new Competence();
    competence.setName("Testcompetence");
    competence.persist(); //test fails if this line is removed
    Competence competenceFromDb = competenceRepository.findOne(competence.getId());

    assertEquals(competence.getName(), competenceFromDb.getName());

    Education education = new Education();
    education.setName("Bachelors Degree");
    competence.addEducation(education);
    competence.persist();


    assertEquals(competence.getEducations(), competenceFromDb.getEducations());
}

如果我删除上述行,则会出现以下异常:

Throws

java.lang.NullPointerException
at com.x.entity.Competence.addEducation(Competence.java:54)

Competence.class:

@JsonIgnoreProperties({"nodeId", "persistentState", "entityState"})
@NodeEntity
public class Competence {

    @RelatedTo(type = "EDUCATION", elementClass = Education.class)
    private Set<Education> educations;

    public Set<Education> getEducations() {
        return educations;
    }

    public void addEducation(Education education) {
        this.educations.add(education);
    }
}

Education.class

@JsonIgnoreProperties({"nodeId", "persistentState", "entityState"})
@NodeEntity
public class Education {

    @GraphId
    private Long id;

    @JsonBackReference
    @RelatedTo(type = "COMPETENCE", elementClass = Competence.class, direction = Direction.INCOMING)
    private Competence competence;

    @Indexed
    private String name;

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

The test below fails if I remove the first persist(). Why do I need to persist the NodeEntity in order for the Set to be instantiated? Is there some better way to do this? I don't want to have to write to the database more often than nessesary.

 @Test
public void testCompetenceCreation() {
    Competence competence = new Competence();
    competence.setName("Testcompetence");
    competence.persist(); //test fails if this line is removed
    Competence competenceFromDb = competenceRepository.findOne(competence.getId());

    assertEquals(competence.getName(), competenceFromDb.getName());

    Education education = new Education();
    education.setName("Bachelors Degree");
    competence.addEducation(education);
    competence.persist();


    assertEquals(competence.getEducations(), competenceFromDb.getEducations());
}

If i remove the mentioned line, the exception bellow occurs:

Throws

java.lang.NullPointerException
at com.x.entity.Competence.addEducation(Competence.java:54)

Competence.class:

@JsonIgnoreProperties({"nodeId", "persistentState", "entityState"})
@NodeEntity
public class Competence {

    @RelatedTo(type = "EDUCATION", elementClass = Education.class)
    private Set<Education> educations;

    public Set<Education> getEducations() {
        return educations;
    }

    public void addEducation(Education education) {
        this.educations.add(education);
    }
}

Education.class

@JsonIgnoreProperties({"nodeId", "persistentState", "entityState"})
@NodeEntity
public class Education {

    @GraphId
    private Long id;

    @JsonBackReference
    @RelatedTo(type = "COMPETENCE", elementClass = Competence.class, direction = Direction.INCOMING)
    private Competence competence;

    @Indexed
    private String name;

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

︶ ̄淡然 2024-12-21 21:41:11

您运行的 SDN 版本是什么?

因为在第一个持久化之前,实体是分离的,并且 AJ 不处理字段(例如创建托管集)。持久创建节点将其连接到实体,从那时起直到事务提交您的实体被附加并且所有更改都将被写入。

它只在提交时写入数据库,因此不用担心太多写入。所有其他更改将仅保存在您的交易内存中。也许您还应该使用 @Transactional 注释测试方法。

您可以为此创建一个 JIRA 问题吗?以便提供一致的处理。 (问题在于,当您自己初始化设置时,它可能也会抱怨。)

另外两件事:

  • 由于您的教育<--能力之间的关系可能是相同的,并且应该只是朝另一个方向导航,因此您必须提供相同的 在注释中输入名称。
  • 例如教育<-[:PROVIDES]-能力

  • 此外,如果你不调用 persist 你的实体将不会被创建,然后 findOne 通过返回null

What version of SDN are you running?

Because up until the first persist the entity is detached and AJ doesn't take care of the fields (like creating the managed set). Persist creates the node at connects it to the entity, from then on until the transaction commits your entity is attached and all the changes will be written through.

It only writes to the db at commit, so no worries about too many writes. All the other changes will just be held in memory for your transaction. Probably you should also annotate the test method with @Transactional.

Can you create a JIRA issue for this? So that a consistent handling is provided. (Problem being that it probably also complains when you initialize the set yourself.)

Two other things:

  • as your relationship between Education<--Competence is probably the same and should just be navigated in the other direction you must provide the same type name in the annotation.
  • e.g. Education<-[:PROVIDES]-Competence

  • also if you don't call persist your entity will not be created and then the findOne by returning null

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文