2016-08-20 10 views
0

当初、私は、次のSQLのためのJPA CriteraiBuilderを使用してコードを書くための要件ました:JPA CriteriaBuilderは関係のないテーブルに対して外部結合を残しましたか?

SELECT ve.col_1, 
    (SELECT vm.col_4 
    FROM table2 vm 
    WHERE vm.col_2 = ve.col_2 
    AND vm.col_3 = ve.col_3 
) as col_a 
FROM table1 ve; 

をしかし、私は、select句でサブクエリを追加することはできませんことを学びました。そこで、このように左外部結合を使用するようにクエリを変更しました。

SELECT ve.col_1, 
    vm.col_4 as col_a 
FROM table1 ve, 
    table2 vm 
WHERE 
vm.col_2 (+) = ve.col_2 
AND vm.col_3 (+) = ve.col_3; 

ここで、table1とtable2は、外部キーを使用する直接関係はありません。対応するJPAエンティティは次のようになります。

Table1.java -> 

@Column(name = "COL_1") 
private String col_1; 

@Column(name = "COL_2") 
private String col_2; 

@Column(name = "COL_3") 
private String col_3; 

@OneToOne(fetch = FetchType.LAZY) 
@JoinColumns({ 
    @JoinColumn(name="COL_2"), 
    @JoinColumn(name="COL_3") 
}) 
private Table2 table2; 


Table2.java -> 

@Column(name = "COL_4") 
private String col_4; 

@Column(name = "COL_2") 
private String col_2; 

@Column(name = "COL_3") 
private String col_3; 

私のコードは次のようになります。その後、私は使用して値を取得しようとしています

final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); 

final CriteriaQuery<SearchTO> query = criteriaBuilder.createQuery(
     SearchTO.class); 
Root<Table1> root = query.from(Table1.class); 

final Join<Table1, Table2> joinTable2 = root.join(Table1_.table2, 
     JoinType.LEFT); 

joinTable2.get(Table2_.col_4) 

それから、今、私はエラーを取得していますよう:

A Foreign key refering com.Table2 from com.Table1 has the wrong number of column 

表2はarouあり注釈@Idを持つ6列と@Id注釈を持つ2列のみを変更することはできません。

私に教えてください:

  • 私のアプローチ1(SELECT句のサブクエリ)のためCriteriaBuilderを使用してコードを記述することが可能です。表2は、表1のすべての参照を持っていませんのでご了承くださいアプローチ2について述べたように、私はこの左外側を実装する方法

  • のthatsができない場合には、参加します。

私はプレーンなJPA APIを使用しています。 DBはOracle11gです。 JDKのバージョンは1.7です。アプローチ1については

+0

にここに助けることができる任意の専門家を述語を追加しますか? – user613114

答えて

0

:あなたは、基準クエリのサブクエリを書くことができます

Subquery<Entity1> subquery = cq.subquery(Entity1.class); 
    Root fromSubQuery = subquery.from(Entity1.class); 
    subquery.select(cb.max(fromSubQuery.get("startDate"))); 
    subquery.where(cb.equal(fromSubQuery.get("xyzId"), fromRootOfParentQuery.get("xyzId"))); 

としてそれを使用します。アプローチ2については

Root<Entity2> entity2 = cq.from(Entity2.class); 
Predicate maxDatePredicate = cb.and(cb.equal(entyty2.get("startDate"), subquery)); 

: がために2つのエンティティ間の関係を有するより他に方法はありません左結合。リレーションシップのプライベート変数をゲッター&セッターなしで定義し、その変数を左結合の設定に使用することができます。 はその後criteriaBuilder

関連する問題