Google App Engine(Java)数据库自动生成ID

时间:2014-05-12 00:38:24

标签: java database google-app-engine google-cloud-datastore

在Google App Engine Java中,

当我这样做时:

ProjectData pd = new ProjectData();
pd.id = null;  // let Objectify auto-generate the project id
pd.dateCreated = date;
datastore.put(pd); // put the project in the db so that it gets assigned an id

当运行" datastore.put(pd)"时,数据库将自动为每个pd分配唯一的ID。 但是,如果我添加父键字段:

ProjectData pd_new= new ProjectData();
pd_new.id = null;  // let Objectify auto-generate the project id
pd_new.parentKey= new Key<OtherData>(OtherData.class, anotherId);
pd_new.dateCreated = date;
datastore.put(pd_new);

即使ID仍然会自动生成,它也不再是唯一的。 ID总是一样的。例如,我在数据库中有7个ProjectData,它们的ID都是&#34; 5629499534213120&#34;

我的数据结构是

public class ProjectData {
  @Id Long id;
  @Parent Key<OtherData> parentKey;
  long dataCreated; 
}  

我在这里做错了什么,这让我困扰了好几天。


BTW,我可以通过手动分配每个来修复它

pd_new.id = System.currentTimeMillis();

但我不认为这是一种合适的方式。

2 个答案:

答案 0 :(得分:3)

为Andrei的回答添加更多细节:

在AppEngine中,有5个部分组成了一个Key,并且只有这5个部分共同保证了AppEngine中所有键的唯一性:

  1. 您的应用的ID。
  2. 命名空间,用于多租户应用程序。
  3. 实体类型名称。
  4. 完整的祖先道路。
  5. 此实体的ID。
  6. 因此,不同类型的实体可能具有相同的ID,此外,可能具有SAME类型但具有不同祖先路径的实体具有相同的ID 。这样做的一个必然结果是,如果你有一个对象,但是改变它的父对象,它会创建一个完整的新对象 - 它不会更新现有对象。因此,如果实体可以重新制作父级,则不应将关系建模为AppEngine中的父子关系。

    因此,如果你正在使用Objectify,我建议的一件事就是只公开你的对象公开KEY(可能是网页安全字符串版本),而不公开ID。您拥有的另一个选项是使用字符串ID,但在保存之前使用UUID.randomUUID填充它。

答案 1 :(得分:1)

这是正确的行为。为什么打扰你?

为了get()来自数据存储区的实体,您需要创建其密钥。为此,您需要父键和子实体ID。这使得此键始终是唯一的(父实体始终具有不同的ID),即使其他父实体的子实体具有相同的ID。