Избежание n + 1 активного извлечения ассоциации дочерних элементов коллекции
У меня есть следующие классы:
@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 {
// ...
}
Теперь я в принципе хочу загрузить всеBase
, но стараюсь загружать бары, когда это применимо, поэтому я использую следующий запрос:
SELECT b FROM Base b LEFT JOIN FETCH b.bars
Несмотря на то, что это работает, кажется, генерирует проблему SELECT N + 1 для сущностей Bar:
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?
Я пробовал что-то вроде следующего запроса, который, очевидно, не работает, так как это коллекция:
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
и хотя это позволяет мне ссылаться на дочернюю коллекцию, похоже, она не загружает коллекцию баров, что является моей целью.
Было бы неплохо объяснить, почему это происходит, так как я не могу понять это.