我有以下课程:
@Entity
@Table(name = "base")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING)
@ForceDiscriminator
public class Base {
// ...
}
@Entity
@DiscriminatorValue("foo")
public class Foo extends Base {
@OneToMany( mappedBy = "foo", cascade=CascadeType.ALL )
private List<Bar> bars = new ArrayList<Bar>();
// ...
}
@Entity
public class Bar {
@ManyToOne (optional = false)
@JoinColumn(name = "foo_id" )
private Foo foo;
@OneToOne
@JoinColumn(name = "baz_id", nullable = false)
private Baz baz;
//...
}
@Entity
public class Baz {
// ...
}
现在我基本上想加载 all Base
,但在适用时急切加载栏,所以我使用以下查询:
SELECT b FROM Base b LEFT JOIN FETCH b.bars
虽然这可行,但它似乎为 Bar 实体生成了一个 SELECT N+1 问题:
Hibernate: /* SELECT b FROM Base b LEFT JOIN FETCH b.bars */ SELECT ...
Hibernate: /* load com.company.domain.Baz */ SELECT ...
Hibernate: /* load com.company.domain.Baz */ SELECT ...
是否可以告诉 hibernate 急切地为子集合中的每个元素加载关联而不诉诸 N+1 选择?
我尝试了以下查询的内容,由于它是一个集合,因此显然不起作用:
SELECT b FROM Base b LEFT JOIN FETCH b.bars LEFT JOIN FETCH b.bars.baz
//Results in: illegal attempt to dereference collection [Foo.id.bars] with element property reference [baz]
我也尝试过使用IN(b.bars) bars
,虽然这允许我引用子集合,但它似乎并没有急切地加载 bar 集合,这是我的目标。
解释为什么会发生这种情况也很好,因为我似乎无法弄清楚。