2016-04-20 9 views
0

Wie kann ich alle Viele-zu-Viele-Beziehungen mit einer minimalen Anzahl von Abfragen abrufen? Ich meine ohne n+1 queries. 3 - es ist normalWie werden alle Viele-zu-Viele-Beziehungen in einer minimalen Anzahl von Abfragen abgerufen?

ich eine Einheit haben:

@Entity 
@Table(name = "tags") 
public class Tag { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    private Long id; 

    @Column(name = "title") 
    private String title; 
} 

@Entity 
@Table(name = "stations") 
public class Station { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    private Long id; 

    @Column(name = "title") 
    private String title; 
} 

@Entity 
@Table(name = "songs") 
public class Song { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    private Long id; 

    @Column(name = "title") 
    private String title; 

    @ManyToMany 
    @JoinTable(
      name = "songs_stations", 
      joinColumns = { 
        @JoinColumn(
          name = "song_id", 
          referencedColumnName = "id" 
        ) 
      }, 
      inverseJoinColumns = { 
        @JoinColumn(
          name = "station_id", 
          referencedColumnName = "id" 
        ) 
      } 
    ) 
    private List<Station> stations; 

    @ManyToMany 
    @JoinTable(
      name = "songs_tags", 
      joinColumns = { 
        @JoinColumn(
          name = "song_id", 
          referencedColumnName = "id" 
        ) 
      }, 
      inverseJoinColumns = { 
        @JoinColumn(
          name = "tag_id", 
          referencedColumnName = "id" 
        ) 
      } 
    ) 
    private List<Tag> tags; 
} 

Und ein Repository:

public interface SongRepository extends CrudRepository<Song, Long> { 

    @Query("SELECT s FROM Song s LEFT JOIN FETCH s.tags LEFT JOIN FETCH s.stations") 
    public List<Song> completeFindAllSongs(); 
} 
  • so, ich nicht eifrig Laden in completeFindAllSongs() Ursache für cannot simultaneously fetch multiple bags
  • verwenden können
  • Kann nicht verwenden @NamedEntityGraph
  • Und ich kann die Daten nicht manuell geladen werden, denn ich habe keinen Zugriff auf songs_tags Tisch
  • Bitte geben Sie nicht @LazyCollection

Was soll ich tun, zu benutzen?

Antwort

2

so, kann ich nicht eifrig Laden in completeFindAllSongs() verwenden Ursache können nicht gleichzeitig mehrere Beutel

Dieser Fehler weggehen holen sollten, wenn Sie Ihre Einheiten ändern „Set“ statt "zu verwenden, Liste "für OneToMany und ManyToMany Beziehungen.

Edit: Also auf Ihre Frage zu beantworten ist: Sie benötigen nur 1 Abfrage. Verwenden Sie einfach Sätze und eifrig holen, was Sie wollen.

+0

ja es funktioniert, aber was ist, wenn ich brauche Liste – sata

1

Beachten Sie, dass durch mehrere Sammlungen beitreten holen Sie vollen Kartesisches Produkt zwischen den Sammelreihen zu schaffen, die eine riesige negativen Auswirkungen auf die Leistung sowohl auf der Datenbank und Anwendungsseite haben kann.

Möglicherweise möchten Sie mit batch size zu berücksichtigen, die Sammlungen in Chargen zu initialisieren.

+0

das ist, warum ich 3 einzelne Abfragen statt einer mit Joins sehen möchte) – sata

+0

'@ BatchSize' es ist ein wirklich gutes Zeug. Vielleicht hat Jpa so etwas? – sata

+0

Nein, vorläufig gibt es keine JPA-äquivalente Annotation; Momentan lässt JPA die meisten Lazy-Loading-Details an die Provider zurück, um die sie sich kümmern müssen. –

Verwandte Themen