无法更改或删除节点与 Neo4j OGM 和 Spring 引导数据之间的关系
Unable to change or delete relationship between nodes with Neo4j OGM and Spring Boot Data
我在使用 Spring Boot (v1.5.10) 和 Neo4j OGM(v2.1.6,使用 Spring Data Neo4j v4.2.10 删除或更改两个节点之间的现有关系时遇到问题).我发现使用旧 Neo4j OGM 版本(如 1.x.something)的人报告的类似问题的一些痕迹,但是,我认为,它应该在 2.1.6 和最新的 Spring Boot v1 版本中早已消失。因此,我不知道这是回归还是我没有以正确的方式使用 API。
所以,我的节点实体定义如下:
@NodeEntity
public class Task {
@GraphId
private Long id;
private String key;
@Relationship(type = "HAS_STATUS")
private Status status;
public Task() {
}
public Long getId() {
return id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
@NodeEntity
public class Status {
@GraphId
private Long id;
private String key;
@Relationship(type = "HAS_STATUS", direction = Relationship.INCOMING)
private Set<Task> tasks;
public Status() {
tasks = new HashSet<>();
}
public Long getId() {
return id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Set<Task> getTasks() {
return tasks;
}
public void addTask(Task task) {
tasks.add(task);
}
public boolean removeTask(Task task) {
if(this.hasTask(task)) {
return this.tasks.remove(task);
}
return false;
}
public boolean hasTask(Task task) {
return this.tasks.contains(task);
}
}
这是用类似 Cypher 的样式表示的方式:
(t:Task)-[:HAS_STATUS]->(s:Status)
这是尝试更新任务状态的服务方法:
public void updateTaskStatus(Task task, Status status) {
Status prevStatus = task.getStatus();
if(prevStatus != null) {
prevStatus.removeTask(task);
this.saveStatus(prevStatus);
}
task.setStatus(status);
if(status != null) {
status.addTask(task);
this.saveStatus(status);
}
this.saveTask(task);
}
作为更新的结果,我得到了两个 HAS_STATUS
关系到两个不同的 Status 节点(旧的和新的),或者,如果我尝试删除现有的关系,没有任何反应(旧的关系仍然存在)
可以在 GitHub 此处找到说明该问题的完整演示:
https://github.com/ADi3ek/neo4j-spring-boot-demo
非常欢迎任何可以帮助我解决该问题的线索或建议! :-)
如果您使用 @Transactional
注释您的命令(因为这是加载实体的地方),它将起作用。
潜在的问题是,如果您加载一个实体,它将使用一个新会话(上下文)打开一个新事务,找到关系并在上下文中缓存有关它们的信息。由于操作已完成,事务(和会话)随后将关闭。
随后的 save/update 未找到打开的事务,因此将打开一个新事务(具有新的会话/会话上下文)。执行保存时,它查看当前状态下的实体,不再查看旧关系。
两个答案:
- 这是一个错误 ;(
编辑: 经过几天的思考,我恢复了上面的说法。这不是真正的错误,而更像是意外行为。 SDN没有错。它使用两个会话(每个操作一个)来完成工作,并且由于没有人告诉它在一个事务中完成工作,因此加载的对象不是 'managed' 或 'attached' (如在 JPA 中)到会话上下文。
- 您可以通过为您的工作单元使用显式事务来解决这个问题
我将关闭 SDN 的问题,并尝试将所有信息迁移到 GitHub 上的两个问题之一,因为它是一个 OGM 问题。
我在使用 Spring Boot (v1.5.10) 和 Neo4j OGM(v2.1.6,使用 Spring Data Neo4j v4.2.10 删除或更改两个节点之间的现有关系时遇到问题).我发现使用旧 Neo4j OGM 版本(如 1.x.something)的人报告的类似问题的一些痕迹,但是,我认为,它应该在 2.1.6 和最新的 Spring Boot v1 版本中早已消失。因此,我不知道这是回归还是我没有以正确的方式使用 API。
所以,我的节点实体定义如下:
@NodeEntity
public class Task {
@GraphId
private Long id;
private String key;
@Relationship(type = "HAS_STATUS")
private Status status;
public Task() {
}
public Long getId() {
return id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
@NodeEntity
public class Status {
@GraphId
private Long id;
private String key;
@Relationship(type = "HAS_STATUS", direction = Relationship.INCOMING)
private Set<Task> tasks;
public Status() {
tasks = new HashSet<>();
}
public Long getId() {
return id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Set<Task> getTasks() {
return tasks;
}
public void addTask(Task task) {
tasks.add(task);
}
public boolean removeTask(Task task) {
if(this.hasTask(task)) {
return this.tasks.remove(task);
}
return false;
}
public boolean hasTask(Task task) {
return this.tasks.contains(task);
}
}
这是用类似 Cypher 的样式表示的方式:
(t:Task)-[:HAS_STATUS]->(s:Status)
这是尝试更新任务状态的服务方法:
public void updateTaskStatus(Task task, Status status) {
Status prevStatus = task.getStatus();
if(prevStatus != null) {
prevStatus.removeTask(task);
this.saveStatus(prevStatus);
}
task.setStatus(status);
if(status != null) {
status.addTask(task);
this.saveStatus(status);
}
this.saveTask(task);
}
作为更新的结果,我得到了两个 HAS_STATUS
关系到两个不同的 Status 节点(旧的和新的),或者,如果我尝试删除现有的关系,没有任何反应(旧的关系仍然存在)
可以在 GitHub 此处找到说明该问题的完整演示:
https://github.com/ADi3ek/neo4j-spring-boot-demo
非常欢迎任何可以帮助我解决该问题的线索或建议! :-)
如果您使用 @Transactional
注释您的命令(因为这是加载实体的地方),它将起作用。
潜在的问题是,如果您加载一个实体,它将使用一个新会话(上下文)打开一个新事务,找到关系并在上下文中缓存有关它们的信息。由于操作已完成,事务(和会话)随后将关闭。
随后的 save/update 未找到打开的事务,因此将打开一个新事务(具有新的会话/会话上下文)。执行保存时,它查看当前状态下的实体,不再查看旧关系。
两个答案:
- 这是一个错误 ;(
编辑: 经过几天的思考,我恢复了上面的说法。这不是真正的错误,而更像是意外行为。 SDN没有错。它使用两个会话(每个操作一个)来完成工作,并且由于没有人告诉它在一个事务中完成工作,因此加载的对象不是 'managed' 或 'attached' (如在 JPA 中)到会话上下文。
- 您可以通过为您的工作单元使用显式事务来解决这个问题
我将关闭 SDN 的问题,并尝试将所有信息迁移到 GitHub 上的两个问题之一,因为它是一个 OGM 问题。