Vermeidung von n+1 eager-fetching des Kindes collection-element association

Habe ich die folgenden Klassen:

@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 {
    //...
}

Ich jetzt im Grunde wollen laden alle Base, aber eifrig laden bars, wenn zutreffend, also benutze ich folgende Abfrage:

SELECT b FROM Base b LEFT JOIN FETCH b.bars

Während dies funktioniert, es scheint zu generieren, eine Auswahl von N+1 problem für die Bar Personen:

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 ...

Ist es möglich zu sagen, hibernate eifrig laden Sie eine Zuordnung für jedes element in der child-Sammlung ohne Rückgriff auf N+1 Wählt?

Habe ich versucht, etwas entlang der Linien von Sie die folgende Abfrage, die offensichtlich nicht funktionieren, da seine Sammlung:

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]

Ich auch versucht, mit Hilfe IN(b.bars) bars, und während dies ermöglicht es mir, Verweis auf die untergeordnete Sammlung, scheint es nicht zu eifrig laden Sie die bars-Sammlung, die ist mein Ziel.

Einer Erklärung, warum dies geschieht, wäre auch schön, da kann ich nicht scheinen, um es herauszufinden.

  • Sind Sie mit "n+1 selects' - Problem für die Baz oder Bar ? Im stacktrace trace, die Sie zur Verfügung gestellt, es sieht aus wie der n+1 wählt, ist für die 'Baz'.
  • Das ist richtig. Die Sammlung Bar-Entitäten wird mit Spannung korrekt geladen, wie erwartet, aber diese eifrigen laden offenbar Kräfte N wählt der Baz-Elemente.
Schreibe einen Kommentar