GAE + Objectify - 参数化类型com.googlecode.objectify.Ref不受支持

时间:2014-07-05 20:59:50

标签: eclipse google-app-engine google-cloud-endpoints objectify

我正在使用Google App engine1.9.3,Eclipse,Objectify5.03。我的班级如下:

import com.googlecode.objectify.Ref;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Load;

@Entity
public class User {

@Id private Long userId;
private String userName;
@Load private Ref<UserDetails> userDetails;
@Load private Ref<UserPassword> userPassword;

//getters & setters 

}

当我尝试通过Eclipse创建此类的google端点时,我收到以下错误: java.lang.IllegalArgumentException:参数化类型com.googlecode.objectify.Ref不受支持

这是我第一次尝试Objectify。

任何想法我做错了什么。从我到目前为止所阅读的内容看,GAE端点和Objectify应该有效,对吗?

2 个答案:

答案 0 :(得分:10)

Google Cloud Endpoints无法序列化Ref对象,因为它是objectify定义的任意对象,因此不支持错误。

限制 Cloud Endpoints 一起使用,因为它不允许使用自定义对象。如果您有兴趣,可以在这一点上有一个完整的讨论主题:Cloud endpoints .api generation exception when using objectify (4.0b1) parameterized key

您必须使用@ApiResourceProperty为方法添加注释,并将其忽略的属性设置为true,如下面的代码所示:

import com.googlecode.objectify.Ref;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Load;
import com.google.api.server.spi.config.AnnotationBoolean;
import com.google.api.server.spi.config.ApiResourceProperty;

@Entity
public class User 
{
    @Id private Long userId;
    private String userName;
    @Load private Ref<UserDetails> userDetails;
    @Load private Ref<UserPassword> userPassword;

    //getters & setters
    @ApiResourceProperty(ignored = AnnotationBoolean.TRUE) 
    public UserDetail getUserDetails(){
    }

    @ApiResourceProperty(ignored = AnnotationBoolean.TRUE) 
    public UserPassword getUserPassword(){
    }
}

如果您仍想使用这些对象中保存的数据,请考虑在您的User类完成加载后,在类中添加一些字段来保存数据并初始化它们:

@Ignore String firstName;
@OnLoad
void trackUserDetails() 
{ 
    this.firstName = getUserDetails().getFirstName(); 
    // add more code here to set other fields, you get the gist
}

但在我看来,更好的方法是重新考虑你班级的设计,或者更反思你正在尝试做的事情。

答案 1 :(得分:0)

ApiResourceProperty注释不适用于Google Emdpoints + Objectify组合,因为Ref或Key是Objectify特定类,Google Endpoints无法识别它们,并且在您尝试生成客户端库时会出错。我更改了User类,如下所示。

 @Id private Long userId;
 @Index private String userName;
 @Load private UserDetails userDetails;
 @Load private UserPassword userPassword;
 @Load private ArrayList<Account> userAccounts;

 //getters and setters

当我按照下面的用户名检索用户时,我会通过getter(一次性)获取User,UserDetails,UserPassword以及用户帐户列表

@ApiMethod(name = "getUserByName", path = "get_user_by_name")
public User getUserByName(@Named("userName") String userName) {

    User user = null;
    try {
         user = ofy().load().type(User.class).filter("userName", userName).first().now();
         if(user != null)
             log.info("UserEndpoint.getUserByName...user retrieved="+user.getUserId());
         else
             log.info("UserEndpoint.getUserByName...user is null");
    } catch(Exception e) {
        log.info("UserEndpoint.getUserByName...exception="+e.getMessage());
    }
    return user;
}

当我在Google Console上使用数据存储查看器查看数据时,我会在User表的userDetails,userPassword和Accounts列中看到一些条目。我假设这些是对各自表中实际数据的引用,而不是数据本身的副本。希望这会有所帮助。