getLinks方法返回已删除的实体,如何防止呢?

时间:2018-11-19 23:44:39

标签: java xodus

下面是我的代码,用于获取Entity的链接列表。它可以工作,但问题是,尽管Entity已被清空,并且是唯一的属性集,即使删除的Entity也会被返回。有没有办法根本不返回已删除的实体?还是有办法将其过滤掉?

EntityId idOfEntity = txn.toEntityId(entityId);
Entity txnEntity = txn.getEntity(idOfEntity);
EntityIterable result = txnEntity.getLinks(Arrays.asList(new String[] {linkName}));
for (Entity entity : result) {
}

2 个答案:

答案 0 :(得分:1)

删除实体时,您有责任检查是否有到删除实体的传入链接。否则会出现所谓的“幻像链接”。您可以设置-Dexodus.entityStore.debug.searchForIncomingLinksOnDelete=truePersistentEntityStoreConfig#setDebugSearchForIncomingLinksOnDelete(true))来调试应用程序中的删除。使用此设置,Xodus会搜索到每个已删除实体的传入链接,如果找到则抛出EntityStoreException。该设置不应在生产环境中使用,因为它会大大降低实体删除的性能。

答案 1 :(得分:0)

这是我想出的完整代码:

@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];
  }