JPA CriteriaBuilder为表没有关系留下了外连接?

时间:2016-08-20 22:03:11

标签: java jpa left-join criteria-api

最初我要求使用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;

但是我了解到,在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有大约6列注释@Id,我无法更改它只有两列@Id注释。

请告诉我:

  • 如果可以使用CriteriaBuilder为我的方法1编写代码(select子句中的子查询)。

  • 如果那不可能,我如何实现方法2中提到的左外连接。请注意,Table2没有表1的任何引用。

请注意我使用普通的JPA API。 DB是Oracle11g。 JDK版本是1.7。

1 个答案:

答案 0 :(得分: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&amp;的关系定义私有变量。 setter并使用该变量来设置左连接。 然后将谓词添加到criteriaBuilder