Objectify并不总是返回结果

时间:2015-04-24 14:48:30

标签: google-app-engine google-cloud-datastore objectify

我正在使用Objectify将数据存储在Google App Engine的数据存储中。我一直在尝试实现两个类之间的一对多关系,但是通过存储参数化键列表。下面的方法在某些时候完美运行,但是其他时候返回一个空数组 - 有谁知道为什么会这样?

它将返回正确的CourseYears列表,或

{
 "items": [
 ]
}

以下是方法:

@ApiMethod(name = "getCourseYears") @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
public ArrayList<CourseYear> getCourseYears(@Named("name") String name){

    Course course = ofy().load().type(Course.class).filter("name", name).first().now();
    System.out.println(course.getName());

    ArrayList<CourseYear> courseYears = new ArrayList<CourseYear>();
    for(Key<CourseYear> courseYearKey: course.getCourseYears()){
        courseYears.add(ofy().load().type(CourseYear.class).id(courseYearKey.getId()).now());
    }

    return courseYears;
}

存储许多CourseYear键的Course类

@Entity
public class Course {
@Id
@Index
private Long courseId;

private String code;

@Index
private String name;

@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
public List<Key<CourseYear>> getCourseYears() {
    return courseYears;
}

@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
public void setCourseYears(List<Key<CourseYear>> courseYears) {
    this.courseYears = courseYears;
} 

@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
     public void addCourseYear(Key<CourseYear> courseYearRef){
    courseYears.add(courseYearRef);
}
@Load
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
List<Key<CourseYear>> courseYears = new ArrayList<Key<CourseYear>>();

...

}

我正在使用API​​资源管理器在调试服务器上调试它。我发现它通常会在开始时工作几次,但是如果我离开并返回API并尝试再次运行它,那么它将不会再开始工作。

有没有人知道会出现什么问题?

非常感谢。

2 个答案:

答案 0 :(得分:1)

您可能希望减少发送到数据存储区的查询量。尝试这样的事情:

Course course = ofy().load().type(Course.class).filter("name", name).first().now();

ArrayList<CourseYear> courseYears = new ArrayList<CourseYear>();
List<Long> courseIds = new List<>();
for(Key<CourseYear> courseYearKey: course.getCourseYears()){
    courseIds.add(courseYearKey.getId());
}
Map<Long, Course> courses = ofy().load().type(CourseYear.class).ids(courseIds).list();
// add all courses from map to you courseYears list

我还强烈建议您更改数据结构/实体:

在您的CourseYears中,在父课程中添加属性Ref<Course> courseRef,并将其编入索引(@Index)。然后按

查询
ofy().load().type(CourseYear.class).filter("courseRef", yourCourseRef).list();

这样您只需要一次查询。

答案 1 :(得分:0)

两个最有可能的候选人是:

  1. 高复制数据存储的最终一致性行为。查询(即你的filter()操作)总是稍微落后,因为索引是异步传播通过GAE的。参见GAE文档。
  2. 您尚未安装ObjectifyFilter。阅读设置指南。如果你没有安装Objectify的最新版本会抛出错误,所以如果你使用的是最新版本,那就不是了。