如果存在则更新节点

update node if exists

我有一个看起来像这样的简单域

@Data
@EqualsAndHashCode(callSuper = true)
@NodeEntity
public class StoryCharacter extends GraphObject {
    @Index(unique = true)
    private String agnosticId;
    private String name;

    @Relationship(type = "FAMILIAR_WITH")
    private Set<StoryCharacter> acquaintances;

    @Labels
    private Set<String> labels = new HashSet<>();

    // Neo4j requires constructor
    public StoryCharacter() {}
}

GraphObject看起来像这样

@Data
abstract class GraphObject {
    @Id
    @GeneratedValue
    private Long id;
}

保存和加载对象的过程如下所示

var session = req.require(SessionFactory.class).openSession();
try (var tx = session.beginTransaction()) {
    session.save(character);
    tx.commit();
}

try (var tx = session.beginTransaction(Type.READ_ONLY)) {
    Collection<StoryCharacter> lists = session.loadAll(StoryCharacter.class,
        AgnosticIdUtils.findByIdQuery(character.getAgnosticId()));
    tx.commit();

    return TPCollectionUtils.getFirstElement(lists);
}

为了生成 angnosticId 我创建了如下所示的侦听器

public class AddCharacterIdListener extends EventListenerAdapter {
    @Override
    public void onPreSave(Event event) {
        StoryCharacter storyCharacter = (StoryCharacter) event.getObject();
        if (StringUtils.isBlank(storyCharacter.getAgnosticId())) {
            var schema = TPCollectionUtils.getFirstElement(storyCharacter.getLabels());
            var id = AgnosticIdUtils.generateId(schema, storyCharacter.getName());
            storyCharacter.setAgnosticId(id);
        }
    }
}

但是当我保存对象时它仍然创建了多次。在数据库中,我有多个具有相同 agnosticId 的节点。

如何让它更新对象而不是重新创建对象?我可能可以更早地生成 agnosticId,然后搜索对象,然后以某种方式将其与现有对象合并......但是还有另一种方法吗?

看来这个问题和有关系。

GraphObject 定义了一个反映内部 Neo4j id 的 id 字段。如果没有定义自定义 id,Neo4j-OGM 将使用此字段来确定对象是否已经在数据库中(具有正 id 集)。

如果 auto index manager feature 设置为合适的值,@Index(unique=true) 注释只是提示 Neo4j-OGM 创建索引。