我有一个简单的域,看起来像这样
@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
然后搜索对象,然后以某种方式将其与现有对象合并......但是还有别的办法吗?
看起来这个问题与使用自定义 ID 搜索对象有一些关系。
GraphObject
定义了一个反映内部 Neo4j id 的id
字段。如果未定义自定义 ID,Neo4j-OGM 将使用此字段来确定对象是否已在数据库中(设置了正 id)。
@Index(unique=true)
注释只是提示 Neo4j-OGM 在将自动索引管理器功能设置为合适的值时创建索引。