在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();
但我不认为这是一种合适的方式。
答案 0 :(得分:3)
为Andrei的回答添加更多细节:
在AppEngine中,有5个部分组成了一个Key,并且只有这5个部分共同保证了AppEngine中所有键的唯一性:
因此,不同类型的实体可能具有相同的ID,此外,可能具有SAME类型但具有不同祖先路径的实体具有相同的ID 。这样做的一个必然结果是,如果你有一个对象,但是改变它的父对象,它会创建一个完整的新对象 - 它不会更新现有对象。因此,如果实体可以重新制作父级,则不应将关系建模为AppEngine中的父子关系。
因此,如果你正在使用Objectify,我建议的一件事就是只公开你的对象公开KEY(可能是网页安全字符串版本),而不公开ID。您拥有的另一个选项是使用字符串ID,但在保存之前使用UUID.randomUUID填充它。
答案 1 :(得分:1)
这是正确的行为。为什么打扰你?
为了get()
来自数据存储区的实体,您需要创建其密钥。为此,您需要父键和子实体ID。这使得此键始终是唯一的(父实体始终具有不同的ID),即使其他父实体的子实体具有相同的ID。