eclipselink batch fetch IN 不适用于多租户
eclipselink batch fetch IN does not work well with multiple tenant
我正在使用@Multitenant(SINGLE_TABLE) 来支持多租户。为了解决 n+1 问题,我使用了 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
所有这些都很完美。
但是当我启用多租户时:
@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 = "SELECT e FROM TestEntity e order by e.id";
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 后它起作用了:
@TenantDiscriminatorColumn(primaryKey = false, ...)
但是,JOIN 和 EXIST 选项仍然不起作用,尽管我不需要它们。
看起来在 JOIN 和 EXIST sql 中所需的 pid 不包含在 where 条件中。这就是它加载所有其他不需要的条目的原因
我正在使用@Multitenant(SINGLE_TABLE) 来支持多租户。为了解决 n+1 问题,我使用了 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
所有这些都很完美。 但是当我启用多租户时:
@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 = "SELECT e FROM TestEntity e order by e.id"; 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 后它起作用了:
@TenantDiscriminatorColumn(primaryKey = false, ...)
但是,JOIN 和 EXIST 选项仍然不起作用,尽管我不需要它们。 看起来在 JOIN 和 EXIST sql 中所需的 pid 不包含在 where 条件中。这就是它加载所有其他不需要的条目的原因