如何在 Spring Data Graph 中持久保存 Neo4J NodeEntity 之间的关系,而无需调用 persist 两次
如果我删除第一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您运行的 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:
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