Warum ist der JPA FetchType EAGER standardmäßig für die @ManyToOne-Beziehung?

8

Ich habe im Hibernate-Quellcode festgestellt, dass FetchType für ManyToOne-Mapping standardmäßig EAGER ist. Während für die OedoMany-Mapping-Standardlademethode Lazy ist. Was ist der spezifische Grund dafür?

    
vatsal mevada 17.12.2014, 06:15
quelle

4 Antworten

21

Aus der JPA 2.0 spe c lauten die Standardeinstellungen wie folgt:

%Vor%

Und im Winterschlaf ist alles Lazy

Aus Hibernate-Dokumenten,

  

Standardmäßig verwendet Hibernate das Lazy-Select-Holen für Sammlungen und   Lazy-Proxy-Abruf für einwertige Verknüpfungen. Diese Standardeinstellungen   Sinnvoll für die meisten Assoziationen in den meisten Anwendungen.

Um Ihre Frage zu beantworten, ist Hibernate eine Implementierung des JPA-Standards. Hibernate hat seine eigenen Macken der Operation, aber laut Hibernate docs

%Vor%

So wird Hibernate jedes Objekt immer mit einer Lazy-Abruf-Strategie laden, egal welche Art von Beziehung Sie deklariert haben.

JPA Spec geht davon aus, dass die meisten Anwendungen im Allgemeinen die Singleton-Relationen standardmäßig begierig, während Multi-Value-Relationen standardmäßig faul sind.

Lesen Sie hier nach mehr

    
Ankur Singhal 17.12.2014 06:19
quelle
3

Der Grund für die Einstellung von EAGER war, dass die frühen JPA 1.0-Entwickler davon ausgegangen waren, dass die Durchsetzung von JPA-Implementierungen zur Unterstützung der dynamischen Initialisierung von Proxies eine sehr wichtige Anforderung wäre. Da jedoch ohne Proxies die Performance enorm leiden würde, unterstützen alle Provider LAZY-Verbände.

Die Standard-EAGER-Abrufstrategie für @ManyToOne und @OneToOne -Verbindungen ist ein Code-Geruch .

Wie in in diesem Artikel erläutert, schlage ich vor, dass Sie alle Verknüpfungen als LAZY setzen und verwenden Sie die JOIN FETCH-Direktive, die in jeder HQL / JPQL- oder Kriterien-Abfrage verfügbar ist.

    
Vlad Mihalcea 17.12.2014 07:48
quelle
0

Wenn Sie lazyfetch in ManyToOne verwenden, müssen Sie Join verwenden, wenn Sie eine Abfrage durchführen, die alle Modelle auf der Viele-Seite

aufruft     
Paul 17.12.2014 06:24
quelle
0

In Hibernate OneToOne und ManyToOne ist standardmäßig nicht faul, auch wenn Sie es explizit als faul setzen.

Beispiel: Es gibt eine Assoziation Eltern- & gt; Kind. Standardmäßig bedeutet dies PARENT_ID Spalte in CHILD Tabelle. ORM weiß nicht, ob Ihr Elternteil tatsächlich ein Kind hat oder es null ist. Wenn ein untergeordnetes Objekt vorhanden ist, muss ein Objekt als übergeordnetes Feld festgelegt werden. Wenn es null ist, muss ORM null setzen. Um herauszufinden, ob es null ist oder nicht, muss ORM die CHILD-Tabelle abfragen. Da eine Abfrage ohnehin durchgeführt wird, ist es sinnvoll, Child sofort zurückzugeben, wenn es existiert.

Um also MTO oder OTO faul zu machen, müssen Sie ORM anweisen, dass Child immer existiert (indem es nicht-optional a.k.a. erforderlich gemacht wird. k.a.nicht-null). Daher weiß ORM, dass es immer vorhanden ist und weiß, dass es einen Proxy anstelle von Child setzen kann.

Alternativ können Sie die Spalte CHILD_ID in der Tabelle PARENT aufbewahren. Wenn Child null ist, ist der Wert im Datensatz ebenfalls null. Aber dafür müssen Sie Konfigurationsoptionen hinzufügen (wie @JoinColumn ), es ist kein Standard.

    
Stanislav Bashkyrtsev 04.01.2017 19:35
quelle