getLinks 方法 returns 删除了实体,如何防止呢?
getLinks method returns deleted Entities, how to prevent it?
下面是我获取 Entity
链接列表的代码。它有效,但问题是即使 Entity
被删除 returned,尽管 Entity
已经清空并且它是唯一的 属性 集合。有没有办法完全不 return 删除的实体?或者有没有办法过滤掉?
EntityId idOfEntity = txn.toEntityId(entityId);
Entity txnEntity = txn.getEntity(idOfEntity);
EntityIterable result = txnEntity.getLinks(Arrays.asList(new String[] {linkName}));
for (Entity entity : result) {
}
删除实体时,您有责任检查是否有指向已删除实体的传入链接。否则会出现所谓的 "phantom links"。您可以在您的应用程序中设置 -Dexodus.entityStore.debug.searchForIncomingLinksOnDelete=true
(PersistentEntityStoreConfig#setDebugSearchForIncomingLinksOnDelete(true)
) 来调试删除。使用此设置,Xodus 搜索每个已删除实体的传入链接,如果找到则抛出 EntityStoreException
。该设置不应在生产环境中使用,因为它会显着降低实体删除性能。
这是我想出的完整代码:
@Override
public boolean deleteEntities(String instance, String namespace, final String entityType) {
final boolean[] success = {false};
final PersistentEntityStore entityStore = manager.getPersistentEntityStore(xodusRoot, instance);
try {
entityStore.executeInTransaction(
new StoreTransactionalExecutable() {
@Override
public void execute(@NotNull final StoreTransaction txn) {
EntityIterable result = null;
if (namespace != null && !namespace.isEmpty()) {
result =
txn.findWithProp(entityType, namespaceProperty)
.intersect(txn.find(entityType, namespaceProperty, namespace));
} else {
result =
txn.getAll(entityType).minus(txn.findWithProp(entityType, namespaceProperty));
}
final boolean[] hasError = {false};
for (Entity entity : result) {
entity.getLinkNames().forEach(linkName -> {
Entity linked = entity.getLink(linkName);
entity.deleteLink(linkName, linked);
});
// TODO: This is a performance issue
final List<String> allLinkNames = ((PersistentEntityStoreImpl) entityStore).getAllLinkNames((PersistentStoreTransaction) entityStore.getCurrentTransaction());
for (final String entityType : txn.getEntityTypes()) {
for (final String linkName : allLinkNames) {
for (final Entity referrer : txn.findLinks(entityType, entity, linkName)) {
referrer.deleteLink(linkName, entity);
}
}
}
if (!entity.delete()) {
hasError[0] = true;
}
}
success[0] = !hasError[0];
}
});
} finally {
// entityStore.close();
}
return success[0];
}
下面是我获取 Entity
链接列表的代码。它有效,但问题是即使 Entity
被删除 returned,尽管 Entity
已经清空并且它是唯一的 属性 集合。有没有办法完全不 return 删除的实体?或者有没有办法过滤掉?
EntityId idOfEntity = txn.toEntityId(entityId);
Entity txnEntity = txn.getEntity(idOfEntity);
EntityIterable result = txnEntity.getLinks(Arrays.asList(new String[] {linkName}));
for (Entity entity : result) {
}
删除实体时,您有责任检查是否有指向已删除实体的传入链接。否则会出现所谓的 "phantom links"。您可以在您的应用程序中设置 -Dexodus.entityStore.debug.searchForIncomingLinksOnDelete=true
(PersistentEntityStoreConfig#setDebugSearchForIncomingLinksOnDelete(true)
) 来调试删除。使用此设置,Xodus 搜索每个已删除实体的传入链接,如果找到则抛出 EntityStoreException
。该设置不应在生产环境中使用,因为它会显着降低实体删除性能。
这是我想出的完整代码:
@Override
public boolean deleteEntities(String instance, String namespace, final String entityType) {
final boolean[] success = {false};
final PersistentEntityStore entityStore = manager.getPersistentEntityStore(xodusRoot, instance);
try {
entityStore.executeInTransaction(
new StoreTransactionalExecutable() {
@Override
public void execute(@NotNull final StoreTransaction txn) {
EntityIterable result = null;
if (namespace != null && !namespace.isEmpty()) {
result =
txn.findWithProp(entityType, namespaceProperty)
.intersect(txn.find(entityType, namespaceProperty, namespace));
} else {
result =
txn.getAll(entityType).minus(txn.findWithProp(entityType, namespaceProperty));
}
final boolean[] hasError = {false};
for (Entity entity : result) {
entity.getLinkNames().forEach(linkName -> {
Entity linked = entity.getLink(linkName);
entity.deleteLink(linkName, linked);
});
// TODO: This is a performance issue
final List<String> allLinkNames = ((PersistentEntityStoreImpl) entityStore).getAllLinkNames((PersistentStoreTransaction) entityStore.getCurrentTransaction());
for (final String entityType : txn.getEntityTypes()) {
for (final String linkName : allLinkNames) {
for (final Entity referrer : txn.findLinks(entityType, entity, linkName)) {
referrer.deleteLink(linkName, entity);
}
}
}
if (!entity.delete()) {
hasError[0] = true;
}
}
success[0] = !hasError[0];
}
});
} finally {
// entityStore.close();
}
return success[0];
}