views:

102

answers:

2

Right, I don't know if I'm barking entirely up the wrong tree here - I'm finding JDO and the Google AppEngine a bit tricky to get the hang of. Anyway, here goes.

I have a class that contains another class as one of it's internal variables (see player1)

  @PersistenceCapable(identityType = IdentityType.APPLICATION)
   public class JDOGame 
   {    
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Long id; 

    @Persistent
    private String map; 

    @Persistent
    private RPCDataPlayer player1;

   // getters, setters, constructors etc...
   }

The class RPCDataPlayer is Serializable and very basic....

public class RPCDataPlayer implements IsSerializable 
{
    public String name;
    public int id;

        // getters & setters & constructors oh my

        public int getId() { return id; }
}

So, my question is...how do I create a query where I can get all the JDOGames that contain an RPCDataPlayer with id = x?

I can't do a query like...

SELECT FROM JDOGame.class.getName() WHERE player1.getId() == x

...so what techniques or suggestions do people have for this to work?

Thanks in advance.

+2  A: 

The Google App Engine Database is not a relational database so you can not do joins. You can persist RPCDataPlayer as a table.

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class RPCDataPlayer {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent(mappedBy = "player1")
    private List<JDOGame> jdoGames = new ArrayList<JDOGame>();

    @Persistent
    public String name;

    @Persistent
    public int id;

    public int getId() {
        return id;
    }

    public Key getKey() {
        return key;
    }

    public void setJdoGames(List<JDOGame> jdoGames) {
        this.jdoGames = jdoGames;
    }

    public List<JDOGame> getJdoGames() {
        return jdoGames;
    }

}

And then you can just query this like this.

SELECT FROM RPCDataPlayer.class.getName() WHERE id == x

Once you have and instance of RPCDataPlayer you can get get JDOGame by calling:

List<JDOGame> jdoGames = rpcDataPlayer.getJdoGames();
Kodova
Thanks Kodova, but I'm not quite sure how this will work. Each game has a single player, but a single player can be part of many games. And what if I add a second player, called player2? Sorry for not being clear.
Spedge
With the updated code you can pull back all the games for a player. If you add a player you can either add player2 too JDOGame and duplicate the jdoGames in PRCDataPlayer and merge the two lists. The better way would be to create a join table that holds the JDOGame, RCPDataPlayer, and playerNumber. This would require a Many-To-Many relationship which you can read up on here http://code.google.com/appengine/docs/java/datastore/relationships.html#Unowned_Relationships
Kodova
Hmm, righto - thanks Kodova, I get it now. It's getting my head away from Relational Databases that's the tricky bit!
Spedge
+1  A: 

Your field is serialised in the datastore, so you obviously can't do a query in the datastore, hence all of those records need retrieving and the query doing in-memory. When GAE/J finally get their act together and allow people to do that then it will be trivial, until then you need to retrieve all records yourself and do the check.

Nothing to do with joins at all

DataNucleus
Thanks for that, I kinda felt it should have been possible. I'll do it the way above, and bide my time...
Spedge