2016-08-20 95 views
0

起初,我不得不要求使用JPA CriteraiBuilder對於下面的SQL編寫代碼: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 

Table2 has arou nd帶有註解@Id的6列,我不能改變它只有兩個帶有@Id註解的列。

請讓我知道:

  • 如果能夠編寫出使用CriteriaBuilder代碼爲我的方法1(在SELECT子句中的子查詢)。

  • 如果這是不可能的,我如何實現這個方法2中提到的左外連接。請注意Table2沒有任何Table1引用。

請注意,我使用的是簡單的JPA API。 DB是Oracle11g。 JDK版本是1.7。

+0

任何專家誰可以幫忙嗎? – user613114

回答

0

對於方法1:你可以寫子查詢條件查詢

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"))); 

使用它作爲:

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

對於方法2: 有比擁有兩個實體之間的關係沒有其他辦法左加入。您可以定義私有變量的關係,而無需使用getter & setter,並使用該變量設置左連接。 然後將謂詞添加到criteriaBuilder