1

datanucleus-appengine の最終バージョン 2.0.0 にアップグレードした後、クエリ API を介して JDOQL クエリを使用すると、フェッチ グループが無視されるように見えるようになりました。ライブラリのバグなのか、これが間違っているのかわかりません。

他のエンティティへの複数の 1:M リスト参照を含む「ユーザー」エンティティが定義されています。これらの参照のフェッチは、フェッチ グループを介して制御します。たとえば、次のようになります。

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

上記の定義により、私の理解は次のとおりです。

  • デフォルトのフェッチ グループのみが使用されている場合、関係はまったくフェッチされません。
  • 'bits' フェッチ グループが指定されている場合、userHistory と userBranding をフェッチする必要があります。
  • 'content' フェッチ グループが指定されている場合は、userContent をフェッチする必要があります。

JDOQL を使用して電子メール フィールドでユーザーをフェッチする場合、どのフェッチ グループが指定されているかに関係なく、リレーションはまったくフェッチされません。getById() を使用してユーザーをフェッチすると、フェッチ グループが期待どおりに適用されます。

L2 キャッシュをオフにしました (jdoquery.xml で NONE に設定)。

フェッチに使用しているテストケースを以下に示します (バージョン 2.0.0-final を使用すると失敗し、バージョン 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());
    }

私はこれについて間違った方法で進んでいますか?

4

0 に答える 0