After upgrading to the 2.0.0-final version of datanucleus-appengine, fetch groups now appear to be ignored when using JDOQL queries via the Query API. I'm not sure whether it's a bug in the library or I'm doing this wrong.
I have a 'User' entity defined which contains multiple 1:M List references to other entities. We control the fetching of these references via fetch groups, e.g:
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true")
@FetchGroups({@FetchGroup(name="bits",
members=@Persistent(name="userHistory"),
@Persistent(name="userBranding")}),
@FetchGroup(name="content", members={@Persistent(name="userContent")})})
public class User implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private String username;
@Persistent
private String email;
@Persistent(mappedBy = "contentUser", defaultFetchGroup = "false")
@Element(dependent = "true")
@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering",value="contentKey asc"))
private List<Content> userContent;
@Persistent(mappedBy = "historyUser", defaultFetchGroup = "false")
@Element(dependent = "true")
@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "createdDate asc"))
private List<History> userHistory;
@Persistent(mappedBy = "brandingUser", defaultFetchGroup = "false")
@Element(dependent = "true")
private List<MediaBranding> userBranding;
...
}
With the above definition, my understanding is:
- None of the relations are fetched when only the default fetch group is used.
- If the 'bits' fetch group is specified, userHistory and userBranding should be fetched.
- If the 'content' fetch group is specified, userContent should be fetched.
When using JDOQL to fetch the user by the email field, regardless of which fetch groups are specified, none of the relations are fetched. If I use getById() to fetch the User, the fetch groups are applied as expected.
I have turned L2 caching off (set to NONE in jdoquery.xml).
The testcase I'm using to fetch is shown below (it fails using version 2.0.0-final, passes with version 1.0.10).
@SuppressWarnings("unchecked")
@Test
public void testAddRetrieveUserByJDOQLQueryFetchGroups() {
PersistenceManager pm;
User u = persistUserAndFriends();
pm = getPMF().getPersistenceManager();
User result = null;
try {
pm.getFetchPlan().addGroup("bits");
pm.getFetchPlan().addGroup("content");
log.info("Groups in fetch plan: " + pm.getFetchPlan().getGroups());
Query query = pm.newQuery(User.class);
query.setFilter("email == emailParam");
query.declareParameters("java.lang.String emailParam");
List<User> results = (List<User>) query.execute("hello@site.net");
assertEquals(1, results.size());
result = results.get(0);
pm.makeTransient(result, true);
} finally {
pm.close();
}
assertNotNull("User history should be fetched", result.getUserHistory());
assertNotNull("User branding should be fetched", result.getUserBranding());
assertEquals("Should be two history children", 2, result.getUserHistory().size());
assertEquals("Should be two branding children", 2, result.getUserBranding().size());
assertEquals("Should be a content child", 1, result.getUserContent().size());
}
Am I going about this the wrong way?