2016-08-20 203 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