Iyyappan S
Iyyappan S

Reputation: 61

Query two entities in Google App Engine JDO


Am new to google appengine and jdo. I do not know how to write a query in JDO with two entities. I have UserProfile and UserFeed entity like as below.

@PersistenceCapable
public class UserProfile {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;

@Persistent
private String firstName;

@Persistent
private String lastName;

@Persistent
private List<Key> friendProfileKeys;
}

@PersistenceCapable
public class UserFeed {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;

@Persistent
private Key profileKey;

@Persistent
private String comment;   

@Persistent
private UserFeedType userFeedType;//Friends,Public
}

Below query I used to get list of feeds that user posted.

final Query query = pm.newQuery(UserFeed.class);
final List v;

query.setFilter("profileKey == paramUserProfileKey");
query.declareParameters("com.google.appengine.api.datastore.Key paramUserProfileKey");

v = (List) query.execute(profile.getKey());

Please help me to get list of feeds that user and his friends posted and also public posts.

Upvotes: 0

Views: 683

Answers (1)

MikO
MikO

Reputation: 18741

As @DataNucleus said in his comment, GAE Datastore doesn't support join queries, so I'm afraid it's impossible to retrieve all you want to retrieve in a single query...

As far as I understand you have 2 choices:

The 1st choice is to use several queries: one query asking for all the public posts, then other query like the one you wrote to get all the feeds of the user, other to get all his friends and lastly one query for each friend, asking for their posts...

The 2nd choice is to use owned relationships. This way you have to change your fields of type Key (the "foreign keys", not the primary ones!) and use fields of the actual classes. For example, you should have a field like this:

@Persistent
private List<UserProfile> friendProfiles;

and

@Persistent
private UserProfile profile;

This way, as said also in the GAE/J documentation, when you retrieve for example an UserFeed, you can easily get the associated User just using:

retrievedUserFeed.getProfile();

and you could also access the friends of the writer of a retrieved feed by:

retrievedUserFeed.getProfile().getFriendProfiles();

These owned relationship have a behaviour that I can't really explain you in detail (see previous link), but basically when you retrieve an entity that has an owned relationship with other entity, if you don't touch the correspondent field, the related entity is never retrieved. In the previous example, if you retrieve a UserFeed but you never use the method getProfile() the UserProfile is never loaded in memory, thus saving resources...

By the way, if you use this method, I strongly suggest you to have a relationship from UserProfile to UserFeed such as:

@Persistent
private List<UserFeed> ownedFeeds;

Because you will want to navigate from UserProfile to UserFeed and not only the opposite way... (Note: this is a design issue independent of GAE and JDO and whatever implementation)

Upvotes: 1

Related Questions