Java GAE数据存储:持久化引用对象
我正在尝试将Java对象持久化到GAE数据存储 我不确定如何持久化具有(“非平凡”)引用对象的对象。 也就是说,假设我有以下内容。Java GAE数据存储:持久化引用对象,java,google-app-engine,google-cloud-datastore,Java,Google App Engine,Google Cloud Datastore,我正在尝试将Java对象持久化到GAE数据存储 我不确定如何持久化具有(“非平凡”)引用对象的对象。 也就是说,假设我有以下内容。 public class Father { String name; int age; Vector<Child> offsprings; //this is what I call "non-trivial" reference //ctor, getters, setters... } public class C
public class Father {
String name;
int age;
Vector<Child> offsprings; //this is what I call "non-trivial" reference
//ctor, getters, setters...
}
public class Child {
String name;
int age;
Father father; //this is what I call "non-trivial" reference
//ctor, getters, setters...
}
公共类父{
字符串名;
智力年龄;
向量派生;//这就是我所说的“非平凡”引用
//克托尔,盖特,塞特。。。
}
公营儿童{
字符串名;
智力年龄;
父亲;//这就是我所说的“非琐碎”引用
//克托尔,盖特,塞特。。。
}
名称字段在每个类型域中都是唯一的,并且被视为主键
为了持久化“平凡”(String,int)字段,我只需要添加正确的注释。到现在为止,一直都还不错。
然而,我不明白我应该如何坚持引用的家庭酿造(孩子、父亲)类型。
我应该:
矢量子串代码>变成矢量子序列代码>?如果是这种情况,我如何在运行时处理对象?我是否只是从Class.getName
中查询主键来检索引用的对象
put()
操作后,转换每个这样的引用以保存数据存储提供给我的实际密钥?也就是说,矢量子代代码>变为矢量offspringsHashKeys代码>
我已经阅读了所有与GAE相关的官方文件/示例。在整个过程中,它们始终保持数据存储本机支持的“琐碎”引用(例如,在留言簿示例中,仅字符串和长字符串)。我的项目中有使用GAE/JPA创建父/子关系的示例。看看与身份验证相关的实体是如何相互关联的 一对一(请参见UserAccount.java和PersistentUser.java): 一对多(参见PersistentUser.java): 另外,请注意构造函数中的KeyFactory是如何用于具有父级的实体还是不具有父级的实体
@Id
private Key key;
// this entity has a parent
public PersistentUser(final Key key, final String username) {
this.key = KeyFactory.createKey(key, getClass().getSimpleName(), username);
...
}
// this entity does not have a parent
public UserAccount(final String username) {
this.key = KeyFactory.createKey(getClass().getSimpleName(), username);
....
}
希望这对你有帮助。我无法从这个问题判断您使用的是JPA还是JDO。如果您在
子项中引用了父项
,在父项中引用了子项
人,那么假设父项和子项之间的关系是双向的,您就有可能出现不一致(即,每个孩子的父亲都应该在该父亲的孩子的ren列表中)。只需要两个参考中的一个
这两种解决方案都会奏效,但将孩子名单留在父亲手中有两个缺点:
对父对象的每次访问都会将列表键下载到子对象。如果有许多键,这可能会导致不必要的开销
我相信GAE将列表的大小限制为5000项
- 请参阅谷歌appengine文档以下部分,以获得更清晰的理解(关系、交易)
- 还可以阅读JDO中的可分离对象
- 要查询选择性列(或字段),请阅读JDO中的fetchgroups
对于您的问题,您有几个选项:
- 拥有一对多关系(对象将在同一实体组中)在此处,您可以在父对象(父类)中拥有子对象列表。这将把所有对象放在同一实体组中。如果您不想每次提取父对象时都提取子对象,您可以从“默认提取组”中删除子对象
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Father {
@PrimaryKey
@Persistent
private String name;
@Persistent
private int age;
@Persistent(mappedBy = "father", defaultFetchGroup = "false")
private List childern;
}
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Child {
@Persistent
@PrimaryKey
private String name;
@Persistent
private Father dad;
}
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Father {
@PrimaryKey
@Persistent
private String name;
@Persistent
private int age;
@Persistent
private List childern;
}
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Child {
@Persistent
@PrimaryKey
private String name;
@Persistent
private Key dad;
}
@PersistenceCapable(identityType=identityType.APPLICATION,detaccable=“true”)
公课父亲{
@主键
@持久的
私有字符串名称;
@持久的
私人互联网;
@持久性(mappedBy=“father”,defaultFetchGroup=“false”)
私人名单儿童;
}
@PersistenceCapable(identityType=identityType.APPLICATION,detaccable=“true”)
公营儿童{
@持久的
@主键
私有字符串名称;
@持久的
私人爸爸;
}
- 存储键而不是引用的无主关系:
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Father {
@PrimaryKey
@Persistent
private String name;
@Persistent
private int age;
@Persistent(mappedBy = "father", defaultFetchGroup = "false")
private List childern;
}
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Child {
@Persistent
@PrimaryKey
private String name;
@Persistent
private Father dad;
}
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Father {
@PrimaryKey
@Persistent
private String name;
@Persistent
private int age;
@Persistent
private List childern;
}
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Child {
@Persistent
@PrimaryKey
private String name;
@Persistent
private Key dad;
}
@PersistenceCapable(identityType=identityType.APPLICATION,detaccable=“true”)
公课父亲{
@主键
@持久的
私有字符串名称;
@持久的
私人互联网;
@持久的
私人名单儿童;
}
@PersistenceCapable(identityType=identityType.APPLICATION,detaccable=“true”)
公营儿童{
@持久的
@主键
私有字符串名称;
@持久的
私钥dad;
}
在这种情况下,您必须管理引用完整性,如果必须在单个事务中更新/添加它们,还必须确保它们位于同一实体组中
在我看来,如果我要模拟一个真实世界(父亲和孩子)的场景,我会选择“拥有关系”的路线,因为,真的,一个男人可以有多少个孩子;)。当然,还有一个额外的问题,你一次要更新多少个父亲
希望这有帮助,干杯 你读过了吗?实际上我有点纠结于此。还不知道怎么服用。此外,我可以明确地说,孩子是父亲“拥有”的,没有父亲就没有任何意义。@Drew-应用程序引擎文档是使用JDO的一个很好的资源,但我发现编程Google app engine()对于JPA的使用是一个更好的参考。这个网站有很多很好的参考资料、示例和食谱。你有#1的来源吗?在我看来,延迟加载不应该有太多开销。此外,entities键已经包含获取其父项所需的信息,无论是否存在通过@ManyToOne等定义的实际关系。请看2009年发布的Google I/O演示文稿的第20页。。。我不知道不一致的部分。然而,在我的场景中,获取父对象通常意味着fetchi
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Father {
@PrimaryKey
@Persistent
private String name;
@Persistent
private int age;
@Persistent
private List childern;
}
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Child {
@Persistent
@PrimaryKey
private String name;
@Persistent
private Key dad;
}