2016-09-11 78 views
2

我在使用EclipseLink在JavaEE Web應用程序中執行分頁時遇到問題。JPQL EclipseLink分頁

目標實體:

@Entity 
@JsonIdentityInfo(generator=JSOGGenerator.class) 
@NamedQueries({ 
    @NamedQuery(
     name = Project.QUERY_FIND_FOR_ADMIN, 
     query = "SELECT DISTINCT p " + 
       "FROM Project p " + 
       "LEFT JOIN FETCH p.documents " + 
       "LEFT JOIN FETCH p.projectManager " + 
       "LEFT JOIN FETCH p.watchingUsers " + 
       "LEFT JOIN FETCH p.users " + 
       "LEFT JOIN FETCH p.scheme " + 
       "ORDER BY p.id", 
     hints = { 
      @QueryHint(name = QueryHints.LEFT_FETCH, value = "p.documents.states") 
//   ,@QueryHint(name = QueryHints.JDBC_FETCH_SIZE, value = Project.ITEMS_PER_PAGE) // does not change anything 
//   ,@QueryHint(name = QueryHints.JDBC_MAX_ROWS, value = Project.ITEMS_PER_PAGE) // results in a LIMIT statement 
     } 
    ) 
}) 
public class Project extends BaseEntity { 

    public static final String ITEMS_PER_PAGE = "" + 2; 

    ... 
} 

一個BaseDAO

public abstract class BaseEntityDAO<Entity> extends AbstractDAO { 

    ... 

    protected List<Entity> executeQuery(String queryName, Map<String, ?> parameters, final int firstResult) { 
     TypedQuery<Entity> query = prepareQuery(queryName, parameters); 
     query.setFirstResult(firstResult); 
     query.setMaxResults(Integer.parseInt(Project.ITEMS_PER_PAGE)); 
     return query.getResultList(); 
    } 

} 

這將導致以下查詢:

// Logging 
[2016-09-11T13:16:26.141+0200] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=28 _ThreadName=Thread-8] [timeMillis: 1473592586141] [levelValue: 800] [[ 
    page: 1]] 
// Logging 
[2016-09-11T13:16:26.141+0200] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=28 _ThreadName=Thread-8] [timeMillis: 1473592586141] [levelValue: 800] [[ 
    first row: 0]] 

[2016-09-11T13:16:26.143+0200] [glassfish 4.1] [FINE] [] [org.eclipse.persistence.session./file:/Users/timtoheus/NetBeansProjects/discanno/target/swan-2.0/WEB-INF/classes/_SwanPU.sql] [tid: _ThreadID=32 _ThreadName=http-listener-1(5)] [timeMillis: 1473592586143] [levelValue: 500] [[ 
    SELECT DISTINCT t1.ID, t1.Name, t1.CREATOR_ID, t1.COLORSCHEME_ID, t0.ID, t0.Name, t0.TOKENIZATIONLANG, t0.Scheme FROM SCHEME t1 LEFT OUTER JOIN PROJECT t0 ON (t0.Scheme = t1.ID)]] 

[2016-09-11T13:16:26.144+0200] [glassfish 4.1] [FINE] [] [org.eclipse.persistence.session./file:/Users/timtoheus/NetBeansProjects/discanno/target/swan-2.0/WEB-INF/classes/_SwanPU.sql] [tid: _ThreadID=28 _ThreadName=http-listener-1(1)] [timeMillis: 1473592586144] [levelValue: 500] [[ 
    SELECT DISTINCT t1.ID AS a1, t1.Name AS a2, t1.TOKENIZATIONLANG AS a3, t1.Scheme AS a4, t0.ID AS a5, t0.Name AS a6, t0.Text AS a7, 
    t0.project_fk AS a8, t2.ID AS a9, t2.Completed AS a10, t2.LastEdit AS a11, t2.document_fk AS a12, t2.user_fk AS a13, 
    t3.ID AS a14, t3.CreateDate AS a15, t3.EMail AS a16, t3.Lastname AS a17, t3.Password AS a18, t3.Prename AS a19, t3.Role AS a20, 
    t3.session AS a21, t4.ID AS a22, t4.CreateDate AS a23, t4.EMail AS a24, t4.Lastname AS a25, t4.Password AS a26, t4.Prename AS a27, 
    t4.Role AS a28, t4.session AS a29, t5.ID AS a30, t5.CreateDate AS a31, t5.EMail AS a32, t5.Lastname AS a33, t5.Password AS a34, 
    t5.Prename AS a35, t5.Role AS a36, t5.session AS a37, t6.ID AS a38, t6.Name AS a39, t6.CREATOR_ID AS a40, t6.COLORSCHEME_ID AS a41 F 
    ROM PROJECT t1 LEFT OUTER JOIN DOCUMENT t0 ON (t0.project_fk = t1.ID) 
    LEFT OUTER JOIN STATE t2 ON (t2.document_fk = t0.ID) 
    LEFT OUTER JOIN (PROJECTS_MANAGER t7 JOIN Users t3 ON (t3.ID = t7.MANAGER_ID)) ON (t7.PROJECT_ID = t1.ID) 
    LEFT OUTER JOIN (PROJECTS_WATCHINGUSERS t8 JOIN Users t4 ON (t4.ID = t8.WATCHINGUSER_ID)) ON (t8.PROJECT_ID = t1.ID) 
    LEFT OUTER JOIN (USERS_PROJECTS t9 JOIN Users t5 ON (t5.ID = t9.USERS_ID)) ON (t9.PROJECT_ID = t1.ID) 
    LEFT OUTER JOIN SCHEME t6 ON (t6.ID = t1.Scheme) 
    ORDER BY t1.ID 
    LIMIT ? OFFSET ? 
    bind => [2, 0]]] 
// Logging 
[2016-09-11T13:16:28.885+0200] [glassfish 4.1] [INFO] [] [] [tid: _ThreadID=28 _ThreadName=Thread-8] [timeMillis: 1473592588885] [levelValue: 800] [[ 
    number of results: 1]] 

正如你可以看到查詢利用LIMIT和OFFSET並正確地綁定所需的參數,但總是返回相同的結果,而不管page/OFFSET是什麼參數是。它總是返回'Project1',但數據庫中共有6個項目(pgAdmin和IntelliJ可以證明這一點)。另外將ORDER BY更改爲name/id或增加'Project.ITEMS_PER_PAGE'也不會改變任何內容。期望的行爲應該返回聲明爲'Project.ITEMS_PER_PAGE'的行數,而不是一個。我想避免編寫一個本地SQL查詢。

由於這裏列出的PostgreSQL應該由EclipseLink的支持: https://www.eclipse.org/eclipselink/documentation/2.6/concepts/app_tl_ext001.htm

表達「限制」,「FETCH第一排」和「偏移」不被支持JPQL。我也嘗試了一些如上所述的QueryHints。奇怪的是,如果我在Postgres中手動執行查詢,它會正確返回所需數量的結果。

我希望有人能給我一個提示。

環境:GlassFish的4.1和PostgreSQL 9.3〜,的EclipseLink 2.6.2

回答

1

嘗試刪除你的左外連接 - 他們真的不與分頁工作,如分頁選項是行級,而外部連接在ManyToMany關係增加了完整讀取實體所需的行數。這很可能導致你的實體跨越多行,所以即使你要求下一個'實體',你只能得到下一行......碰巧是同一個第一個實體。

嘗試使用批處理使用分頁時,而不是使用上多對多和一對多的關係讀取query hint或映射

+0

唉唉,有趣的annotation!謝謝!我會嘗試。 – Rooky