リレーションが定義されていない 2 つのテーブルがありますが、基準ビルダー API を使用して、それらを 1 つのクエリに結合しようとしています。
このクエリは、私が望むように機能します-両方のテーブルからの行を同期します:
Root<E_Application> root = q.from(E_Application.class);
Root<E_Searcher> root2 = q.from(E_Searcher.class);
q.where(cb.equal(root.get(E_Application_.packageName),
root2.get(E_Searcher_.packageName)));
q.select(cb.sum(cb.literal(1)));
出てくるクエリは次のとおりです。select sum(1) from application t0 cross join application_searcher t1 where (t0.package_name = t1.package_name);
ただし、別の結合を追加すると:
Root<E_Application> root = q.from(E_Application.class);
Root<E_Searcher> root2 = q.from(E_Searcher.class);
Join<E_Application, E_AppState> j1 =
root.join(E_Application_.publicAppState);
q.where(cb.equal(root.get(E_Application_.packageName),
root2.get(E_Searcher_.packageName)));
q.select(cb.sum(cb.literal(1)));
余分な交差結合を取得し、最終的にデカルト積になります。SELECT SUM(1) FROM application t0 CROSS JOIN application t1 CROSS JOIN application_search t3 INNER JOIN application_state t2 ON t1.PUBLICAPPSTATE_ID = t2.id WHERE (t0.package_name = t3.package_name)
これを防ぐ方法はありますか (アプリケーションとサーチャーの間の適切な関係を定義することを除く)? これは仕様の適切な実装ですか? 結果のクエリが、明示的に要求していないルートを効果的に持ち、制御できないのはちょっと奇妙です...
重要な場合、データベースはpostgresです。
PS 関係がない理由は、これら 2 つのテーブルの PK が同じであり、エンティティ参照でもある PK を持つことができないためです。