带有祖先键的PersistenceManager.getObjectById

时间:2013-03-25 16:05:54

标签: java google-app-engine google-cloud-datastore jdo datanucleus

我正在使用JDO为数据存储区创建一个Java GAE应用程序。

我有这两个类用户和文件夹。

@PersistenceCapable
public class User {    
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;
  @Persistent
  private Folder rootFolder;    
  //getters and setters...
}

@PersistenceCapable
public class Folder {   
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;
  @Persistent
  private List<Folder> subfolders;    
  //getters and setters...
}

我想在 ID(长)的情况下检索一个文件夹,所以我尝试这样做:

Key key = KeyFactory.createKey(Folder.class.getSimpleName(), 371);
folder = this.pm.getObjectById(Folder.class, key);

但这不起作用。它抛出了这个例外:

org.datanucleus.exceptions.NucleusObjectNotFoundException: 
Could not retrieve entity of kind Folder with key Folder(371)

我认为这是因为该文件夹的 Key 也包含其祖先的键,但我的问题是我无法知道所有祖先路径给出其ID的文件夹。

我可以知道它是路径中的第一个祖先,即拥有根文件夹的用户。我发现有一个Query.setAncestor(Key)方法,这可能适用于此,但它仅适用于查询,而不适用于“密钥查找”......

有人知道怎么做吗?

1 个答案:

答案 0 :(得分:2)

我不熟悉Java方面,但数据存储在Java / Python上基本相同。

一旦开始使用祖先,ids / names就不再是实体的唯一标识符。唯一标识符是id加上整个祖先路径的组合。在不同的祖先下可以有多个具有相同id的实体。没有整个祖先路径,您就没有唯一的密钥。

您可以做的最好的事情是查找与该ID匹配的实体,然后在返回的集合中找出您想要的实体。您可以在Query之后再次执行getObjectById以获取一致的版本,但这对新实体没有帮助。

您可能想要重新审视一些事情,比如在这种情况下您是否真的需要祖先。如果这样做,您需要设计一些位置来存储文件夹的整个祖先路径,以便在执行getObjectById时可以引用它。或者,如果您计划将文件夹名称设置为唯一,请使用名称而不是ID,以便更容易查找。等