Hibernate 提取 parent 的所有 child 记录,而不仅仅是受约束的 children
Hibernate pulls up all child records of a parent, not just the constrained children
我得到了 Cat 实体 parent,CatDts 是一对多 child 集合。
我想得到所有 CatDt.name='a' 的猫。生成的 sql 查询是正确的,但在访问 CatDts 集合时,将返回所有 child 记录,而不仅仅是名称为 'a' 的记录。感谢任何帮助,谢谢!
表格
Cat CatDt
id id name cat_id
---- --- --- ---
1 100 a 1
2 101 a 2
102 xyz 2
所以我只需要 1-100、2-101 但它也给了我 2-102
猫实体
private List<CatDt> catDts = new ArrayList<CatDt>();
@OneToMany(fetch = FetchType.LAZY, mappedBy = "cat", cascade=CascadeType.ALL)
public List<CatDt> getCatDts() {
if(this.catDts==null){
this.catDts = new ArrayList<CatDt>();
}
return this.catDts;
}
CatDt 实体
private Cat cat;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
@JoinColumn(name = "CAT_ID", nullable = false)
public Cat getCat() {
return this.cat;
}
服务
public List<Cat>findAllByOption(CatOption options){
QCat cat = QCat.cat;
QCatDt catDt = QCatDt.catDt;
List<Cat> cats = jpaQueryFactory.selectFrom(cat)
.innerJoin(catDt).on(cat.id.eq(catDt.cat.id).and(catDt.name.eq("a")))
.where(cat.status.eq(new BigDecimal(0))).fetch();
return cats;
}
测试
@Test
public void testCatWithOptionsJpaQuery(){
CatOption options = new CatOption();
options.setStatus(new BigDecimal(0));
options.setName("a");
List<Cat> catList = catService.findAllByOption(options); //-->returns 2 rows
for(Cat cat:catList){
logger.info("--" + cat.toString()); //-->gets the child collection catDts and pulls out all rows, not just constrained ones
}
Assert.notNull(catList, "categories returned cannot be null!");
}
我检查日志并发现,在下面的测试行中,sql 查询和连接很好,只有 returns 2 行 Cat.
catService.findAllByOption(options)
但是当我迭代那 2 个 Cat objects 时,Hibernate 会取出所有对应的 CatDt child 集合(总共 3 个)。
那么我如何才能只获得 child name='a' 的记录?
更新 1
当执行到达测试循环中的下一行时,它会抛出单独的 select 语句,这就是返回 3 条记录而不是 2 条记录的方式。我认为这就是 orm 应该工作的方式但是如何得到刚好约束children?
logger.info("--" + cat.toString())
所以我通过创建一个 pojo 来保存我需要的所有连接的结果字段来解决这个问题。
我的 service/repo 使用 querydsl 加入和过滤,返回 pojo 列表。
我认为 Hibernate 非常适合一个 table crud,但对于复杂的连接和结果,我们可以使用自定义 objects 和 Querydsl。
或者我也可以通过 parents 循环并使用 Hibernate 的 @Filter。
我得到了 Cat 实体 parent,CatDts 是一对多 child 集合。 我想得到所有 CatDt.name='a' 的猫。生成的 sql 查询是正确的,但在访问 CatDts 集合时,将返回所有 child 记录,而不仅仅是名称为 'a' 的记录。感谢任何帮助,谢谢!
表格
Cat CatDt
id id name cat_id
---- --- --- ---
1 100 a 1
2 101 a 2
102 xyz 2
所以我只需要 1-100、2-101 但它也给了我 2-102
猫实体
private List<CatDt> catDts = new ArrayList<CatDt>();
@OneToMany(fetch = FetchType.LAZY, mappedBy = "cat", cascade=CascadeType.ALL)
public List<CatDt> getCatDts() {
if(this.catDts==null){
this.catDts = new ArrayList<CatDt>();
}
return this.catDts;
}
CatDt 实体
private Cat cat;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
@JoinColumn(name = "CAT_ID", nullable = false)
public Cat getCat() {
return this.cat;
}
服务
public List<Cat>findAllByOption(CatOption options){
QCat cat = QCat.cat;
QCatDt catDt = QCatDt.catDt;
List<Cat> cats = jpaQueryFactory.selectFrom(cat)
.innerJoin(catDt).on(cat.id.eq(catDt.cat.id).and(catDt.name.eq("a")))
.where(cat.status.eq(new BigDecimal(0))).fetch();
return cats;
}
测试
@Test
public void testCatWithOptionsJpaQuery(){
CatOption options = new CatOption();
options.setStatus(new BigDecimal(0));
options.setName("a");
List<Cat> catList = catService.findAllByOption(options); //-->returns 2 rows
for(Cat cat:catList){
logger.info("--" + cat.toString()); //-->gets the child collection catDts and pulls out all rows, not just constrained ones
}
Assert.notNull(catList, "categories returned cannot be null!");
}
我检查日志并发现,在下面的测试行中,sql 查询和连接很好,只有 returns 2 行 Cat.
catService.findAllByOption(options)
但是当我迭代那 2 个 Cat objects 时,Hibernate 会取出所有对应的 CatDt child 集合(总共 3 个)。 那么我如何才能只获得 child name='a' 的记录?
更新 1
当执行到达测试循环中的下一行时,它会抛出单独的 select 语句,这就是返回 3 条记录而不是 2 条记录的方式。我认为这就是 orm 应该工作的方式但是如何得到刚好约束children?
logger.info("--" + cat.toString())
所以我通过创建一个 pojo 来保存我需要的所有连接的结果字段来解决这个问题。
我的 service/repo 使用 querydsl 加入和过滤,返回 pojo 列表。
我认为 Hibernate 非常适合一个 table crud,但对于复杂的连接和结果,我们可以使用自定义 objects 和 Querydsl。
或者我也可以通过 parents 循环并使用 Hibernate 的 @Filter。