web-dev-qa-db-ja.com

JPA Criteria APIを使用して無関係なエンティティを結合する方法

2つのデータベーステーブルには外部キー関係があります。

これらは、JPAによって2つのエンティティ[〜#〜] a [〜#〜]および[〜#〜] b [〜#〜]にマップされますが、結合列エンティティから手動で削除されるため、JPAワールドクラスでは[〜#〜] a [〜#〜]および[〜#〜] b [〜#〜]は関連せず、フィールド/プロパティを介して一方から他方に移動することはできません。

JPA Criteria APIを使用して、2つのテーブルを結合するクエリを作成できますか?

インターネットで見つけたすべての例では、目標を達成するために結合列を使用していますが、前述のように、ほとんどの時間は[〜#〜] a [の関係に興味がないので、コードから削除されました。 〜#〜][〜#〜] b [〜#〜]と私はオーバーヘッドの可能性を恐れています。

19
Filippo

まず、外部キー関係はナビゲートのためだけではありません。それらは主に、関係に誤った値が導入されないようにするために役立ちます。また、クエリの最適化のためにデータベースを支援する場合もあります。それを再考することをお勧めします。

とにかく、いくつかの無関係なエンティティを使用するクエリを作成するには、それらをfromroot)エンティティとして配置する必要があります(SQLまたはJPQLで行うように)

SELECT .... FROM Link l, Training t WHERE l.attribute = t.attribute;

Root<Link> rootLink = criteriaQuery.from(Link.class);
Root<Training> rootTraining = criteriaQuery.from(Training.class);
...
criteriaQuery.where(
    criteriaBuilder.equal(rootLink.get(link_.linkAttribute), trainingLink));
22
SJuan76

関連のないエンティティへの参加は最新のJPA仕様(2.1)の対象外です

ただし、Hibernate 5.1.0+およびEclipseLink 2.4.0+はアドホック結合をサポートしています。 http://blog.anthavio.net/2016/03/join-unrelated-entities-in-jpa.html

別の可能性はネイティブクエリです http://www.Oracle.com/technetwork/articles/vasiliev-jpql-087123.html

5
anthavio

JPQL/HQLに変換され、JPA Criteria APIへの拡張としてその機能を提供するBlaze永続性のJPA Criteria実装を使用できます。

Readmeで「Blaze-Persistence JPA-Criteriaモジュールの依存関係」を探してください: https://github.com/Blazebit/blaze-persistence/blob/master/README.md

次に、BlazeCriteriaBuilder cb = BlazeCriteria.get(criteriaBuilderFactory)、最後にblazeCriteriaQuery.getCriteriaBuilder(entityManager)を使用して、JPA基準クエリオブジェクトをレンダリングします。

0

この記事 で説明したように、Hibernate 5.1以降、JPQLとHQLを使用するときに無関係なエンティティを結合できます。

Tuple postViewCount = entityManager.createQuery(
    "select p as post, count(pv) as page_views " +
    "from Post p " +
    "left join PageView pv on p.slug = pv.slug " +
    "where p.title = :title " +
    "group by p", Tuple.class)
.setParameter("title", "Presentations")
.getSingleResult();

ただし、この機能はAPI拡張を必要とするため、Criteria APIでは使用できません。

ソリューション

2つのRootオブジェクトを使用してWHERE句の述語を介してINNER JOINをエミュレートすることもできますが、結果のSQLはこの問題を解決する最良の方法ではありません。

jOOQ の使用を検討する必要があります。可能な方法でテーブルを結合できるほか、生成されたSQLクエリを JPA createNativeQuery に渡してエンティティをフェッチすることもできます。方法。

0
Vlad Mihalcea