[英]JPA CriteriaBuilder left outer join for table with no relations?
Initially I had requirement to write code using JPA CriteraiBuilder for following SQL: 最初,我需要使用JPA CriteraiBuilder为以下SQL编写代码:
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;
But I learnt that, it is not possible to add subquery in select clause. 但是我了解到,不可能在select子句中添加子查询。 So I changed my query to use left outer join like this.
因此,我将查询更改为使用左外部联接,如下所示。
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;
Now table1 and table2 do not have direct relations using foreign keys. 现在,table1和table2没有使用外键的直接关系。 Corresponding JPA entities look like:
相应的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;
My code looks like: 我的代码如下:
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);
Then I am trying to fetch value using: 然后我尝试使用以下方法获取值:
joinTable2.get(Table2_.col_4)
Then now I am getting error as: 然后现在我得到错误为:
A Foreign key refering com.Table2 from com.Table1 has the wrong number of column
Table2 has around 6 columns with annotation @Id and I can not change change it to have only two columns with @Id annotation. Table2大约有6列带有@Id的注释,我无法更改将其更改为只有两列带有@Id的注释。
Please let me know: 请告诉我:
If it is possible to write code using CriteriaBuilder for my approach 1 (subquery in select clause). 如果可以使用CriteriaBuilder为我的方法1(在select子句中的子查询)编写代码。
If thats not possible, how can I implement this left outer join as mentioned for approach 2. Please note that Table2 does not have any references of Table1. 如果那不可能,我如何实现方法2所述的左外部联接。请注意,Table2没有Table1的任何引用。
Please note that I am using plain JPA APIs. 请注意,我使用的是普通的JPA API。 DB is Oracle11g.
DB是Oracle11g。 JDK version is 1.7.
JDK版本是1.7。
For Approach 1: You can write subquery for criteria query 对于方法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" ) ) );
Use it as : 用作:
Root<Entity2> entity2 = cq.from( Entity2.class );
Predicate maxDatePredicate = cb.and( cb.equal( entyty2.get( "startDate" ), subquery ) );
For Approach 2: There is no other way than having relationship between two entities for left join. 对于方法2:除了要在两个实体之间建立左连接关系之外,别无其他方法。 You can define private variable for relationship without getter & setter and use that variable for setting left join.
您可以为没有getter和setter的关系定义私有变量,并使用该变量设置左联接。 Then add the predicate to criteriaBuilder
然后将谓词添加到criteriaBuilder
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.