Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Objectify在Ref<;后面加载对象&燃气轮机;即使未指定@Load_Java_Google App Engine_Google Cloud Endpoints_Objectify - Fatal编程技术网

Java Objectify在Ref<;后面加载对象&燃气轮机;即使未指定@Load

Java Objectify在Ref<;后面加载对象&燃气轮机;即使未指定@Load,java,google-app-engine,google-cloud-endpoints,objectify,Java,Google App Engine,Google Cloud Endpoints,Objectify,我有一个引用用户对象的account对象 @Cache @Entity public final class Account { @Id Long id; @Index private Ref<User> user; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public U

我有一个引用用户对象的account对象

@Cache
@Entity
public final class Account {

    @Id Long id;
    @Index private Ref<User> user;

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    public User getUser() {
        return user.get();
    }
    public void setUser(User user) {
        this.user = Ref.create(user);
    }

}
当我直接使用API资源管理器查询帐户时,我也会同时获得这两个帐户,即嵌入用户的帐户:

200 OK
{ 
"id": "5079604133888000", 
"user": {  "id": "5723348596162560",  
"version": "1402003195251",  
"firstName": "Karl" }, 
"kind": "api#accountItem", 
"etag": "\"30khohwUBSGWr00rYOZuF9f4BTE/Q31EvnQCQ6E9c5YXKEZHNsD_mlQ\""}
这提出了三个问题:

  • Appengine是否总是以本机方式返回嵌入的引用,Objectify是否总是传递它已经知道的对象
  • @Load的确切用途是什么?有没有办法控制这种行为?负载组
  • 我错过什么了吗?为什么不遵守@Load

  • 在示例代码中,您没有指定
    @Load
    ,这意味着加载帐户不会获取
    用户
    。但是,您的
    @ApiMethod
    正在将帐户序列化回客户端,因此访问了
    user
    属性,因此会发出单独的获取来加载用户对象。这就是为什么在调用该方法时会获得用户的信息

    不指定
    @Load
    并不意味着您将无法获得
    用户
    。这意味着您不会检索
    用户
    ,除非您以后特别要求它

    Ref的工作原理如下:

    • 我是一个引用,所以默认情况下我不会获取数据
    • 如果你问我,我会先加载数据,然后回答你
    • 哦,如果你让我自己加载,那么我会先提取数据并准备好给你
    所以这在你的代码中工作得很好。。。但是您的
    @ApiMethod
    正在将您的
    帐户
    对象序列化回客户端。序列化过程将遍历
    帐户
    对象中的每个属性,包括
    用户
    属性。此时,正在访问
    Ref
    ,因此数据将从数据存储中获取,然后返回到客户端

    这使得您的代码非常低效,因为加载
    帐户
    对象时没有
    用户
    信息,但之后(序列化期间)您总是访问
    用户
    信息,并发出单独的获取。从数据存储中批处理
    get
    比单独发出
    get
    更有效

    在您的情况下,您可以执行以下两种操作之一:

  • @Load
    添加到用户属性,以便有效地获取
    帐户
    对象
  • 使您的
    @ApiMethod
    返回一个不同的
    帐户
    对象,而不使用
    用户
    属性(这样可以避免在不需要时获取用户)

  • 上面的选项2非常有用,因为您可以从客户机看到的内容中抽象出内部数据存储结构。你会发现自己经常使用这种模式。

    谢谢@svpino给出的非常详细的答案,我相信这对所有使用objectify with REST的人来说都非常重要。我不清楚,即使我没有从代码中显式地访问Ref,序列化程序也会这样做。如果我在发送到客户端之前显式地将用户对象设置为null会怎么样?
    200 OK
    { 
    "id": "5079604133888000", 
    "user": {  "id": "5723348596162560",  
    "version": "1402003195251",  
    "firstName": "Karl" }, 
    "kind": "api#accountItem", 
    "etag": "\"30khohwUBSGWr00rYOZuF9f4BTE/Q31EvnQCQ6E9c5YXKEZHNsD_mlQ\""}