GAE+Objectify - Parameterized type com.googlecode.objectify.Ref not supported

后端 未结 2 1130
轻奢々
轻奢々 2020-12-20 03:33

I am using Google App engine1.9.3, Eclipse, Objectify5.03. My Class is as follows:

import com.googlecode.objectify.Ref;
import com.googlecode.objectify.annot         


        
相关标签:
2条回答
  • 2020-12-20 04:03

    ApiResourceProperty annotation does not work for Google Emdpoints+Objectify combinations as Ref or Key is Objectify specific class and Google Endpoints does not recognize them and will give a error when you try to generate the Client Libraries. I changed the User class as below.

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

    When I retrieve the user by user name as below, I get the User, UserDetails, UserPassword and also the list of User accounts thru the getters (in one shot)

    @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;
    }
    

    When I use the Datastore Viewer on Google Console to view the data, I see some entries in the userDetails, userPassword and Accounts columns in the User table. I assume that these are references to the actual data in their respective tables and not a copy of the data itself. Hope this helps.

    0 讨论(0)
  • 2020-12-20 04:04

    Google Cloud Endpoints is unable to serialise the Ref object because it is an arbitrary object defined by objectify, therefore not supported as the error indicates.

    This is known limitation with Cloud Endpoints in that it does not allow custom objects to be used. There is a whole discussion thread on this point in particular if you're interested: Cloud endpoints .api generation exception when using objectify (4.0b1) parameterized key

    You will have to annotate your methods with @ApiResourceProperty and set its ignored attribute to true as illustrated in the code below:

    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(){
        }
    }
    

    If you still want to use the data held in those objects then consider adding some fields to your class to hold the data and initialise them after your User class has finished loading like so:

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

    But in my opinion a better approach would be to reconsider the design of your class, or rather rethink what you're trying to do.

    0 讨论(0)
提交回复
热议问题