다중 점유를 지원하기 위해 @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를 제거 후 작동
이클립스는 Entity의 일부로 취급하고있는 것처럼 보입니다. Entity의 id 필드가 모든 임차인에게 고유 할 필요는 없으므로, 뒤에서 복합 PK로 만듭니다. 이것은 "BatchFetchType.IN"일부 데이터베이스에서는 싱글 톤 ID에서만 작동 할 수 있습니다. "라는 문서에서 다루어집니다. EclipseLink가이를 처리하기 위해 다르게 처리 할 수 있기 때문에 최신 버전을 사용해보고 버그를 제출할 수도 있습니다. 대신 다른 batchFetchType 옵션 중 하나를 사용하십시오. – Chris
@Chris 귀하의 의견에 감사드립니다. 나는 최신 버전 2.6.3을 시도했으나 어느 것도 작동하지 않는다. 다른 옵션을 시도해도 JOIN은 중복 된 레코드를 생성하지 않지만 불필요한 레코드를 가져 오려고합니다. 또한 IN은 페이지 매김을 지원할 수있는 것으로 보입니다. – Jacky
죄송합니다, 결과를 놓치지 않습니다. 포함 된 여분의 테이블은 쿼리 처리와 관련된 버그처럼 보입니다. 페이지 생성을 제거하고 다른 옵션을 사용하여 재생하면 관련된 구성 요소를 격리하여 도움을받을 수 있는지 확인하여 쿼리가 오작동을 일으키는 지 확인할 수 있습니다. 다른 옵션을 사용하는 경우 수정이 필요한 부분을 쉽게 찾을 수 있습니다. – Chris