2016-06-16 3 views
2

다중 점유를 지원하기 위해 @Multitenant (SINGLE_TABLE)를 사용하고 있습니다. n + 1 문제를 해결하기 위해 eclipselink의 batch fetch 기능을 사용합니다.eclipselink 배치 가져 오기가 여러 거주자와 잘 작동하지 않습니다.

@Entity 
public class TestEntity implements Serializable { 
    @Id 
    @Column 
    private Long id; 

    @OneToMany(mappedBy = "testEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    @BatchFetch(BatchFetchType.IN) 
    private List<TestEntityLine> lines = new ArrayList<>(); 
} 

@Entity 
public class TestEntityLine implements Serializable { 
    @Id 
    @Column 
    private Long id; 

    @JoinColumn(name = "PID", referencedColumnName = "ID", nullable = true) 
    private TestEntity testEntity; 
} 

내가 사용 쿼리

String boql = "SELECT e FROM TestEntity e order by e.id"; 
    query.setFirstResult(1); // for pagination 
    query.setMaxResults(3); // for pagination 

는 SQL과 결과는 로그 : 완벽하게이 작품의

2016-06-16 10:05:14.558 [main] DEBUG o.e.p.s./.sql - SELECT ID AS a1 FROM TESTENTITY ORDER BY ID LIMIT ? OFFSET ? 
    bind => [3, 1] 
entity-2 
2016-06-16 10:05:14.594 [main] DEBUG o.e.p.s./.sql - SELECT ID, NAME, VALUE, PID FROM TESTENTITYLINE WHERE (PID IN (?,?,?)) 
    bind => [2, 3, 4] 
entityLine-2-3 
entityLine-2-1 
entityLine-2-2 
entity-3 
entityLine-3-2 
entityLine-3-1 
entityLine-3-3 
entity-4 
entityLine-4-3 
entityLine-4-2 
entityLine-4-1 

모두. 하지만 멀티 테넌트 (multi-tenant) 사용할 때 : 내가 사용 쿼리 할 때

@Entity 
public class TestMultiTenantEntity implements Serializable { 
    @Id 
    @Column 
    private Long id; 

    @OneToMany(mappedBy = "testEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    @BatchFetch(BatchFetchType.IN) 
    private List<TestMultiTenantEntityLine> lines = new ArrayList<>(); 
} 

@Entity 
public class TestMultiTenantEntityLine implements Serializable { 
    @Id 
    @Column 
    private Long id; 

    @JoinColumn(name = "PID", referencedColumnName = "ID", nullable = true) 
    private TestMultiTenantEntity testEntity; 
} 

@MappedSuperclass 
@Multitenant(SINGLE_TABLE) 
@TenantDiscriminatorColumn(discriminatorType = DiscriminatorType.INTEGER, primaryKey = true, name = MultiTenantSupport.TENANT_COLUMN_NAME, length = 12, contextProperty = MultiTenantSupport.MULTITENANT_CONTEXT_PROPERTY) 
public abstract class MultiTenantSupport { 

    public static final String MULTITENANT_CONTEXT_PROPERTY = "tenant_id"; 

    public static final String TENANT_COLUMN_NAME = "TENANT_ID"; 

} 

을 :

문자열을 boql = "e.id에 의해 TestEntity 전자 순서에서 전자를 선택합니다"; query.setFirstResult (1); // 페이지 매기기의 경우 query.setMaxResults (3); // 매김

는 SQL 및 결과에 대한 로그 :

2016-06-16 10:17:17.123 [main] DEBUG o.e.p.s./.sql - SELECT TENANT_ID AS a1, ID AS a2 FROM TESTMULTITENANTENTITY WHERE (TENANT_ID = ?) ORDER BY ID LIMIT ? OFFSET ? 
    bind => [1, 3, 1] 
entity-2 
2016-06-16 10:17:17.159 [main] DEBUG o.e.p.s./.sql - SELECT t0.TENANT_ID, t0.ID, t0.NAME, t0.VALUE, t0.PID FROM TESTMULTITENANTENTITYLINE t0, TESTMULTITENANTENTITYLINE t1 WHERE ((((t1.TENANT_ID, t1.PID) IN ((?,?),(?,?),(?,?))) AND (t0.TENANT_ID = ?)) AND (t1.TENANT_ID = ?)) 
    bind => [1, 2, 1, 3, 1, 4, 1, 1] **?????? Why TESTMULTITENANTENTITYLINE joins to itself t0/t1? This produce many duplicated records** 
2016-06-16 10:17:17.227 [main] DEBUG o.e.p.s./.sql - SELECT TENANT_ID, ID FROM TESTMULTITENANTENTITY WHERE (((TENANT_ID = ?) AND (ID = ?)) AND (TENANT_ID = ?)) 
    bind => [1, 1, 1] **?????? I try to fetch record 2,3,4, why it fetch out 1, 5, 6?** 
2016-06-16 10:17:17.267 [main] DEBUG o.e.p.s./.sql - SELECT TENANT_ID, ID FROM TESTMULTITENANTENTITY WHERE (((TENANT_ID = ?) AND (ID = ?)) AND (TENANT_ID = ?)) 
    bind => [1, 5, 1] 
2016-06-16 10:17:17.295 [main] DEBUG o.e.p.s./.sql - SELECT TENANT_ID, ID FROM TESTMULTITENANTENTITY WHERE (((TENANT_ID = ?) AND (ID = ?)) AND (TENANT_ID = ?)) 
    bind => [1, 6, 1] 
entityLine-2-1 
entityLine-2-1 
entityLine-2-1 
entityLine-2-1 
entityLine-2-1 
entityLine-2-1 
entityLine-2-1 
entityLine-2-1 
entityLine-2-1 
entityLine-2-2 
entityLine-2-2 
entityLine-2-2 
entityLine-2-2 
entityLine-2-2 
entityLine-2-2 
entityLine-2-2 
entityLine-2-2 
entityLine-2-2 
entityLine-2-3 
entityLine-2-3 
entityLine-2-3 
entityLine-2-3 
entityLine-2-3 
entityLine-2-3 
entityLine-2-3 
entityLine-2-3 
entityLine-2-3 
entity-3 
entityLine-3-1 
entityLine-3-1 
entityLine-3-1 
entityLine-3-1 
entityLine-3-1 
entityLine-3-1 
entityLine-3-1 
entityLine-3-1 
entityLine-3-1 
entityLine-3-2 
entityLine-3-2 
entityLine-3-2 
entityLine-3-2 
entityLine-3-2 
entityLine-3-2 
entityLine-3-2 
entityLine-3-2 
entityLine-3-2 
entityLine-3-3 
entityLine-3-3 
entityLine-3-3 
entityLine-3-3 
entityLine-3-3 
entityLine-3-3 
entityLine-3-3 
entityLine-3-3 
entityLine-3-3 
entity-4 
entityLine-4-1 
entityLine-4-1 
entityLine-4-1 
entityLine-4-1 
entityLine-4-1 
entityLine-4-1 
entityLine-4-1 
entityLine-4-1 
entityLine-4-1 
entityLine-4-2 
entityLine-4-2 
entityLine-4-2 
entityLine-4-2 
entityLine-4-2 
entityLine-4-2 
entityLine-4-2 
entityLine-4-2 
entityLine-4-2 
entityLine-4-3 
entityLine-4-3 
entityLine-4-3 
entityLine-4-3 
entityLine-4-3 
entityLine-4-3 
entityLine-4-3 
entityLine-4-3 
entityLine-4-3 

을 TESTMULTITENANTENTITYLINE가 T0/T1 자체에 조인 이유는 무엇입니까? 이것은 많은 중복 레코드를 생성합니다.

레코드 2,3,4를 가져 오려고하는데, 왜 1, 5, 6을 꺼내려고합니까?

도와 주시겠습니까? 이게 버그 야? 또는 나는 무엇인가 놓쳤다? 미리 감사드립니다. 나는 다음과 같은 설정으로 기본 키에서 tenant_id를 제거 후 작동

+0

이클립스는 Entity의 일부로 취급하고있는 것처럼 보입니다. Entity의 id 필드가 모든 임차인에게 고유 할 필요는 없으므로, 뒤에서 복합 PK로 만듭니다. 이것은 "BatchFetchType.IN"일부 데이터베이스에서는 싱글 톤 ID에서만 작동 할 수 있습니다. "라는 문서에서 다루어집니다. EclipseLink가이를 처리하기 위해 다르게 처리 할 수 ​​있기 때문에 최신 버전을 사용해보고 버그를 제출할 수도 있습니다. 대신 다른 batchFetchType 옵션 중 하나를 사용하십시오. – Chris

+0

@Chris 귀하의 의견에 감사드립니다. 나는 최신 버전 2.6.3을 시도했으나 어느 것도 작동하지 않는다. 다른 옵션을 시도해도 JOIN은 중복 된 레코드를 생성하지 않지만 불필요한 레코드를 가져 오려고합니다. 또한 IN은 페이지 매김을 지원할 수있는 것으로 보입니다. – Jacky

+0

죄송합니다, 결과를 놓치지 않습니다. 포함 된 여분의 테이블은 쿼리 처리와 관련된 버그처럼 보입니다. 페이지 생성을 제거하고 다른 옵션을 사용하여 재생하면 관련된 구성 요소를 격리하여 도움을받을 수 있는지 확인하여 쿼리가 오작동을 일으키는 지 확인할 수 있습니다. 다른 옵션을 사용하는 경우 수정이 필요한 부분을 쉽게 찾을 수 있습니다. – Chris

답변

1

는 :

@TenantDiscriminatorColumn(primaryKey = false, ...) 

하지만 여전히, 가입 및 내가 그들을 필요로하지 않지만 옵션을 사용할 수 없습니다 존재한다. JOIN과 EXIST SQL에서 필요한 pid가 where 조건에 포함되어 있지 않은 것으로 보입니다. 이것이 다른 불필요한 모든 항목을로드하는 이유입니다.

관련 문제