我正在将现有的Google AppEngine应用程序从主从数据存储(MSD)移动到新的高复制数据存储(HRD)。该应用程序是用Java编写的,使用Objectify 3.1实现持久性。
在我的旧(MSD)应用程序中,我有一个类似于的实体
public class Session {
@Id public Long id;
public Key<Member> member;
/* other properties and methods */
}
在新的(HRD)应用程序中,我将其更改为:
public class Session {
@Id public Long id;
// HRD: @Parent is needed to ensure strongly consistent queries.
@Parent public Key<Member> member;
/* other properties and methods */
}
我需要Session对象与其父Member对象保持强一致。
当我使用谷歌的HRD迁移工具迁移(的工作副本)我的应用程序时,所有成员和会话都在那里。但是,Session对象的所有成员属性都变为null。显然,这些属性没有迁移。
我准备重新设置Session对象的父级,但如果成员属性为null,那是不可能的。有人能解释我做错了什么吗?这个问题能否解决?
@Id和@Parent不是底层实体中的"真实"属性。它们是定义实体的关键的一部分;Objectify将它们映射到POJO上的属性。
您试图进行的转换是GAE中比较复杂的问题之一。请记住,具有不同父级的实体(例如,某个值vs null)是不同的实体;它有一把不同的钥匙。例如,加载一个父级为空的实体,将父级设置为一个值,然后保存该实体,不会更改实体,而是创建一个新实体。您仍然需要删除旧实体并更新任何外键引用。
您的最佳选择是按常规"成员"字段的原样导入数据。您还可以拥有@Parent字段(可以任意调用它;您可以随时重命名它,因为它不是"真实"属性)。迁移后,通过您的数据:
- 加载每个会话
- 检查parentMember是否为null。如果为空:
- 指定parentMember并保存实体
- 删除parentMember为null的实体
如果你这样做的话,要非常小心外键引用。