Question

I have verified that the entity I am looking for is in the datastore. I have verified that the list I pass as a method parameter contains this entity. I am trying to find all objects that have their 'userGmail' contained in the list of strings I pass.

Here is my code

    @SuppressWarnings("unchecked")
@ApiMethod(name = "findFriendsByEmailList")
public CollectionResponse<ZeppaUser> findFriendsByEmailList(
        @Named("emailsList") List<String> emailsList, User user)
        throws OAuthRequestException {

    if (user == null) {
        throw new OAuthRequestException(
                "Null User Authorization Exception, findFriendsByEmailList");
    }

    PersistenceManager mgr = null;
    List<ZeppaUser> execute = null;
    Query query = null;
    try {
        mgr = getPersistenceManager();

        query = mgr.newQuery(ZeppaUser.class);
        query.declareParameters("java.util.List emailListParam");
        query.setFilter("emailListParam.contains( userGmail )");

        execute = (List<ZeppaUser>) query.execute(emailsList);

        query.closeAll();

    } finally {
        mgr.close();
    }

    return CollectionResponse.<ZeppaUser> builder().setItems(execute)
            .build();

}

This is the stack trace I receive from it: enter image description here

Something worth noting: I do not receive this error on lists I pass in that to not contain an element found in the datastore. Just when it does exist which leads me to believe that the Query has located the element but has not been closed or executed into a return parameter correctly. If it is preferable to return List that is more than ok. I have tried multiple variations of this with no success thus far. It is getting quite frustrating.

Was it helpful?

Solution

Ok so I found a way around it.

Lists cannot be passed into ApiEndpoints. That or I didn't figure out the correct way to do it and would LOVE an update on the proper way to do this.

Instead, in my client, I construct a String of emails seperated by a comma and send a string into the parameter as an 'encoded' string list then 'decode' it upon execution. Works well but seems hacky.

here are the methods I used. This is convenient though because it works with iOS as well.

public static String encodeListString(ArrayList<String> stringList){
    StringBuilder stringbuilder = new StringBuilder();
    stringbuilder.append(stringList.get(0));
    if(stringList.size() > 1){
        for( int i = 0; i < stringList.size(); i++){
            stringbuilder.append(",");
            stringbuilder.append(stringList.get(i));
        }
    }

    return stringbuilder.toString();
}

public static List<String> decodeListString(String encodedString){

    char[] characters = encodedString.toCharArray();
    StringBuilder stringbuilder = new StringBuilder();
    int position = 0;
    ArrayList<String> stringList = new ArrayList<String>();
    while(true){
        try {
        char character = characters[position];
        if(character == ','){
            String resultString = stringbuilder.toString();
            stringList.add(resultString);
            stringbuilder = new StringBuilder(); // clear it
        } else {
            stringbuilder.append(character);
        }

        position++;

        } catch (ArrayIndexOutOfBoundsException aiex){
            // List ended
            String resultString = stringbuilder.toString();
            if(!resultString.isEmpty())
                stringList.add(resultString);
            break;
        }

    }

    return stringList;

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top