我正在尝试将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 Child {
String name;
int age;
Father father; //this is what I call "non-trivial" reference
//ctor, getters, setters...
}
名称字段在每个类型域中都是唯一的,并被视为主键。
为了保留“普通”(String,int)字段,我只需要添加正确的注释。到现在为止还挺好。 但是,我不明白我应该如何坚持参考的自酿(儿童,父亲)类型。 我应该:
Vector<Child> offsprings;
变为Vector<String> offspringsNames;
?如果是case,我如何在运行时处理对象?我是否只是从Class.getName
查询主键,以检索refrenced对象?
put()
操作时提供给我的实际密钥?也就是说,Vector<Child> offsprings;
变为Vector<Key> offspringsHashKeys;
?我已阅读所有官方相关的GAE文档/示例。在整个过程中,它们始终保持“琐碎”引用,本地由数据存储区支持(例如,在留言簿示例中,仅限字符串和长整数。)
答案 0 :(得分:0)
我在我的jappstart项目中使用GAE / JPA创建父/子关系的示例。看看身份验证相关实体如何相互关联here。
一对一(参见UserAccount.java和PersistentUser.java):
// parent
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private PersistentUser persistentUser;
// child
@OneToOne(mappedBy = "persistentUser", fetch = FetchType.LAZY)
private UserAccount userAccount;
一对多(参见PersistentUser.java):
@OneToMany(mappedBy = "persistentUser", cascade = CascadeType.ALL)
private Collection<PersistentLogin> persistentLogins;
多对一(参见PersistentLogin.java):
@ManyToOne(fetch = FetchType.LAZY)
private PersistentUser persistentUser;
另外,请注意构造函数中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。
答案 1 :(得分:0)
如果您在父亲的Father
和Child
中提到了Child
,那么假设父与子之间的关系是假的,那么您可能会出现不一致的情况。双向(即每个Child
的父亲应该在该父亲的Child
名单中。只需要两个引用中的一个。
两种解决方案都可行,但保留父亲的儿童名单有两个缺点:
答案 2 :(得分:0)
请参阅以下各节中的google appengine docs以获得更清晰的理解(关系,交易)
另请阅读JDO中可拆卸对象
对于您的问题您有几种选择:
@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;
}
在这种情况下,您必须管理参照完整性,并确保它们在同一实体组中,如果您必须在单个事务中更新/添加它们
国际海事组织,如果我在模拟真实世界(父亲 - 孩子)的情景,我会选择“拥有的关系”路线,因为,真的,一个人可以拥有多少个孩子;)。当然还有一个问题,即你一次要更新多少父亲?
希望这有帮助,欢呼!