2012-12-13 61 views
1

使用Eclipselink 2.4.1,我試圖避免在批量查詢中出現「distinct」關鍵字。文檔建議,當使用批量類型EXISTS時,不使用distinct關鍵字,但根據我的經驗,它在所有情況下都用於檢索多對一關係。例如,我有以下的類在Oracle書面反對SCOTT演示模式:在批量查詢中避免使用不同的關鍵字

@Entity 
public class Emp implements Serializable { 
    @Id private long empno; 
    private String ename; 
    @ManyToOne 
    @JoinColumn(name="DEPTNO") 
    private Dept dept; 
    public Emp() { } 
    public long getEmpno() { return this.empno; } 
    public void setEmpno(long empno) { this.empno = empno; } 
    public String getEname() { return this.ename; } 
    public void setEname(String ename) { this.ename = ename; } 
    public Dept getDept() { return this.dept; } 
    public void setDept(Dept dept) { this.dept = dept; } 
} 

@Entity 
public class Dept implements Serializable { 
    @Id private long deptno; 
    private String dname; 
    public Dept() {} 
    public long getDeptno() { return this.deptno; } 
    public void setDeptno(long deptno) { this.deptno = deptno; } 
    public String getDname() { return this.dname; } 
    public void setDname(String dname) { this.dname = dname; } 
} 

我試圖通過檢索一批員工和部門獲取:

Query query = em.createQuery("select emp from Emp as emp "); 
query.setHint(QueryHints.BATCH_TYPE, BatchFetchType.EXISTS); 
query.setHint(QueryHints.BATCH, "emp.dept"); 
List<Emp> resultList = query.getResultList(); 
resultList.get(0).getDept(); 

下面的SQL生成:

[EL Fine]: sql: 2012-12-12 17:04:21.178--ServerSession(1034011695)--Connection(312759349)--SELECT EMPNO, ENAME, DEPTNO FROM SCOTT.EMP 
[EL Fine]: sql: 2012-12-12 17:04:21.286--ServerSession(1034011695)--Connection(312759349)--SELECT distinct t0.DEPTNO, t0.DNAME FROM SCOTT.DEPT t0 WHERE EXISTS (SELECT t1.EMPNO FROM SCOTT.EMP t1 WHERE (t0.DEPTNO = t1.DEPTNO)) 

有什麼額外的需要,除了要做,以使用EXISTS間歇式,以避免批量查詢使用distinct關鍵字?

+1

請問您使用DISTINCT關鍵字時需要注意什麼? – northpole

+0

這在查詢中是沒有必要的,而且它對我感興趣的情況(它比這個例子有更多的表)造成了一個糟糕的查詢計劃。 – cogitos

回答

1

請註冊一個錯誤。它應該只用於JOIN批處理。

您可以在查詢中將distinct設置爲false來避免它。 (沒有提示,你需要在根ObjectLevelReadQuery上調用dontUseDistinct())。

((ObjectLevelReadQuery)((JpaQuery)query).getDatabaseQuery()).dontUseDistinct();