我试图将Java对象持久化到GAE数据存储区 .
我不确定如何持有具有("non-trivial")引用对象的对象 . 也就是说,假设我有以下内容 .
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)字段,我只需要添加正确的注释 . 到现在为止还挺好 . 但是,我不明白我应该如何坚持引用的自酿(儿童,父亲)类型 . 我是不是该:
-
转换每个此类引用以保存主键(在此示例中为名称String)而不是"actual"对象,因此
Vector<Child> offsprings;
变为Vector<String> offspringsNames;
?
如果是这种情况,我如何在运行时处理对象?我是否只是从Class.getName
查询主键,以检索refrenced对象? -
转换每个这样的引用以保存数据存储在正确
put()
操作时提供给我的实际密钥?也就是说,Vector<Child> offsprings;
变成Vector<Key> offspringsHashKeys;
?
我已经阅读了所有官方相关的GAE文档/示例 . 在整个过程中,它们始终保持数据存储本身支持的引用(例如,在留言簿示例中,仅限字符串和长整数) .
3 回答
请参阅以下章节中的google appengine docs以获得更清晰的理解(关系,交易)
还阅读了有关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;
}`
``
在这种情况下,您必须管理参照完整性,并确保它们在同一个实体组中,如果您必须在单个事务中更新/添加它们
国际海事组织,如果我在建模一个现实世界(父亲 - 孩子)的场景,我会选择“拥有关系”的路线,因为,真的,一个人可以拥有多少个孩子;) . 当然还有一个问题,即你一次要更新多少父亲?
希望这会有所帮助,欢呼!
我在jappstart项目中使用GAE / JPA创建父/子关系的示例 . 看看认证相关实体如何相互关联here .
一对一(参见UserAccount.java和PersistentUser.java):
一对多(参见PersistentUser.java):
多对一(参见PersistentLogin.java):
另外,请注意构造函数中KeyFactory如何用于具有父对象而非父对象的实体 .
希望这对你有所帮助 . 我无法从问题中判断出您使用的是JPA还是JDO .
如果你在父亲的
Child
和Child
中引用Father
而不是你有可能出现不一致,假设父与子之间的关系是双向的(即每个_411774的父亲都应该在那个父亲的名单Child
ren . 只需要两个引用中的一个 .这两种解决方案都可行,但保留父亲的儿童名单有两个缺点:
对Father对象的每次访问都会将列表键下载到子对象 . 如果有许多密钥,这可能会导致不必要的开销 .
我认为GAE将列表的大小限制为5,000个项目 .