更新节点(如果存在)

时间:2019-01-03 18:26:13

标签: java neo4j neo4j-ogm

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

@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,然后搜索对象,然后以某种方式将其与现有对象合并...但是还有另一种方法吗?

1 个答案:

答案 0 :(得分:1)

该问题似乎与searching for object with custom id有一定关系。

GraphObject定义了一个id字段,该字段反映了内部Neo4j ID。如果未定义自定义ID,Neo4j-OGM将使用此字段来确定数据库中是否已存在对象(已设置正ID)。

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