App Engine:相同对象化查询的不同结果
App Engine: different results for same objectify query
我正在使用 App Engine 开发一个小型后端。现在,在用不同的值多次保存一个实体后,我得到了一些奇怪的行为。
我加载实体的代码对于所有实体都是相同的——每个实体都有一个 changeId,所以我只能将更改的实体传输给客户端:
public class VersionableRecordHelper<T extends VersionableRecord> {
final Class<T> clazz;
public VersionableRecordHelper(Class<T> clazz) {
this.clazz = clazz;
}
Query<T> load() {
return ofy().load().type(clazz);
}
List<T> loadOrdered() {
return load().order("changeId").list();
}
public List<T> loadOrdered(Long since) {
return since == null ? loadOrdered() : load().filter("changeId >", since).order("changeId").list();
}
}
客户端然后可以通过提供 since
值来查询 class 的所有对象。例如:
private final VersionableRecordHelper<Cat> helper
= new VersionableRecordHelper<>(Cat.class);
// actually an @ApiMethod, simplified here
public List<Cat> getCats(Long since) {
return helper.loadOrdered(since);
}
我的 Cat 实体如下所示:
@Entity
@Cache
@JsonSerialize(include = JsonSerialize.Inclusion.ALWAYS)
public class Cat extends VersionableRecord {
// some fields, getters, setters
}
public class VersionableRecord {
@Id
private String id;
@Index
private Long changeId;
// getters, setters and more
}
现在,如果我使用 since == 4
执行相同的 REST 请求,我会得到 完全不同的结果 - 有时 changeId == 5, 但是还有 2、3 或 4 - 这甚至是不可能的!
我完全迷失在这里。这是我检查过的:
- 我在测试过程中没有更改记录。事实上,我完全不理会记录超过90分钟。
- 我检查过只有一个应用程序引擎实例是 运行。
- 我尝试刷新内存缓存 - 但相同的 2 个 ObjectifyCache 键仍然存在。
- 内存缓存服务级别为 'Shared'。
- 我偶然检查了
since
的值不为空。所以代码肯定会被执行。
- 目前我使用的是 objectify 版本 5.0.3。来自我的 build.gradle:
compile 'com.googlecode.objectify:objectify:5.0.3'
- 我还通过检查 https://console.developers.google.com/project/project-id/datastore/query?authuser=0
确保实体在数据存储中具有正确的 changeId
有人有什么有用的想法吗?我还检查了不同类型的实体 - 相同的行为。
大胆猜测,这与常见问题 #3 有关:
或者,当 googlecode 死掉时,第三个倒下:
https://github.com/objectify/objectify/wiki/FrequentlyAskedQuestions
您需要安装 ObjectifyFilter
否则您会将会话数据泄露到后续请求中。升级到更新版本的 Objectify;它会给你一个更明确的错误(以复杂化测试和远程api使用为代价,但这是另一回事)。
如果这不是您的问题,您需要更详细地描述您的确切代码。
我正在使用 App Engine 开发一个小型后端。现在,在用不同的值多次保存一个实体后,我得到了一些奇怪的行为。 我加载实体的代码对于所有实体都是相同的——每个实体都有一个 changeId,所以我只能将更改的实体传输给客户端:
public class VersionableRecordHelper<T extends VersionableRecord> {
final Class<T> clazz;
public VersionableRecordHelper(Class<T> clazz) {
this.clazz = clazz;
}
Query<T> load() {
return ofy().load().type(clazz);
}
List<T> loadOrdered() {
return load().order("changeId").list();
}
public List<T> loadOrdered(Long since) {
return since == null ? loadOrdered() : load().filter("changeId >", since).order("changeId").list();
}
}
客户端然后可以通过提供 since
值来查询 class 的所有对象。例如:
private final VersionableRecordHelper<Cat> helper
= new VersionableRecordHelper<>(Cat.class);
// actually an @ApiMethod, simplified here
public List<Cat> getCats(Long since) {
return helper.loadOrdered(since);
}
我的 Cat 实体如下所示:
@Entity
@Cache
@JsonSerialize(include = JsonSerialize.Inclusion.ALWAYS)
public class Cat extends VersionableRecord {
// some fields, getters, setters
}
public class VersionableRecord {
@Id
private String id;
@Index
private Long changeId;
// getters, setters and more
}
现在,如果我使用 since == 4
执行相同的 REST 请求,我会得到 完全不同的结果 - 有时 changeId == 5, 但是还有 2、3 或 4 - 这甚至是不可能的!
我完全迷失在这里。这是我检查过的:
- 我在测试过程中没有更改记录。事实上,我完全不理会记录超过90分钟。
- 我检查过只有一个应用程序引擎实例是 运行。
- 我尝试刷新内存缓存 - 但相同的 2 个 ObjectifyCache 键仍然存在。
- 内存缓存服务级别为 'Shared'。
- 我偶然检查了
since
的值不为空。所以代码肯定会被执行。 - 目前我使用的是 objectify 版本 5.0.3。来自我的 build.gradle:
compile 'com.googlecode.objectify:objectify:5.0.3'
- 我还通过检查 https://console.developers.google.com/project/project-id/datastore/query?authuser=0 确保实体在数据存储中具有正确的 changeId
有人有什么有用的想法吗?我还检查了不同类型的实体 - 相同的行为。
大胆猜测,这与常见问题 #3 有关:
或者,当 googlecode 死掉时,第三个倒下:
https://github.com/objectify/objectify/wiki/FrequentlyAskedQuestions
您需要安装 ObjectifyFilter
否则您会将会话数据泄露到后续请求中。升级到更新版本的 Objectify;它会给你一个更明确的错误(以复杂化测试和远程api使用为代价,但这是另一回事)。
如果这不是您的问题,您需要更详细地描述您的确切代码。