2016-09-11 3 views
2

EclipseLink를 사용하여 JavaEE 웹 응용 프로그램에서 페이지 매김을 구현하는 데 문제가 있습니다.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 원하는 매개 변수를 올바르게 바인딩하지만 페이지/오프셋과 상관없이 항상 동일한 결과를 반환합니다. 매개 변수는입니다. 항상 'Project1'을 반환하지만 데이터베이스에 총 6 개의 프로젝트가 있습니다 (pgAdmin 및 IntelliJ가이를 증명할 수 있음). ORDER BY를 name/id로 변경하거나 'Project.ITEMS_PER_PAGE'를 높이면 아무 것도 변경되지 않습니다. 원하는 동작은 'Project.ITEMS_PER_PAGE'로 선언 된 행 수를 반환해야하며 항상 하나는 아닙니다. 네이티브 SQL 쿼리 작성을 피하고 싶습니다. https://www.eclipse.org/eclipselink/documentation/2.6/concepts/app_tl_ext001.htm

표현식 '제한', 'FIRST 행을 페'와 JPQL에서 지원하지 않는 '오프셋': 여기에 나열된 PostgreSQL을 같이

은 EclipseLink가에 의해 지원 될 필요가 있습니다. 위에서 언급 한 QueryHints도 시도해 보았습니다. 이상한 점은 Postgres에서 쿼리를 수동으로 실행하면 원하는 결과를 제대로 반환한다는 것입니다.

누군가 나에게 힌트를 줄 수 있기를 바랍니다.

환경 : 글래스 피쉬 4.1, PostgreSQL을 ~ 9.3, EclipseLink가 2.6.2

답변

1

왼쪽 외부 조인 제거하십시오 - 매김 옵션은 행 수준에로 외부를 통해 조인 동안 그들은 정말, 페이지 매김 작동하지 않습니다 ManyToMany 관계는 엔티티를 완전히 읽는 데 필요한 행 수를 증가시킵니다. 이것은 엔티티가 여러 행에 걸쳐있을 가능성이 있습니다. 따라서 다음 '엔티티'를 요청하더라도 다음 행만 가져오고 있습니다. 동일한 첫 번째 엔티티에 대해 발생합니다. 배치를 사용하여

시도 대신 매김을 사용하여 사용하는 경우 ManyToMany 및 OneToMany 관계에 읽는 query hint 또는 매핑

+0

아, 흥미에 annotation! 고맙습니다! 나는 그것을 시도 할 것이다. – Rooky