Standard-Abruftyp für Eins-zu-Eins, Viele-zu-Eins und Eins-zu-Viele im Ruhezustand

103

Was ist der Standardabruftyp in Zuordnungen im Ruhezustand?

Was ich nach dem Erkunden kennengelernt habe ist:

  • für eins zu eins ist es eifrig .
  • für eins zu viele ist es faul .

Aber nachdem es in Eclipse getestet wurde, war es für alle eifrig.

Kommt es darauf an, ob ich JPA oder Hibernate verwende?

Richa
quelle
1
Falls Sie immer noch an JPA-Themen beteiligt sind - Ich habe Ihre Frage mit einer neuen Antwort aktualisiert, da die alten für die aktuelle Hibernate-Version veraltet sind.
Alexander Rühl

Antworten:

193

Dies hängt davon ab, ob Sie JPA oder Hibernate verwenden.

Ab der JPA 2.0-Spezifikation lauten die Standardeinstellungen:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

Und im Winterschlaf ist alles faul

AKTUALISIEREN:

Die neueste Version von Hibernate entspricht den oben genannten JPA-Standardeinstellungen.

Ashish Agarwal
quelle
11
"Und im Ruhezustand ist alles faul" hat sich anscheinend in den letzten Versionen geändert. Bitte sehen Sie die Antwort von Alexander Rühl unten .
Dinei
1
Hibernate ist eine der JPA-Implementierungen.
Wenn
Dies ist eine beliebte Abfrage. @ Ashish Agarwal Kannst du bitte die letzte Zeile deiner Antwort aktualisieren? Im Winterschlaf ist es jetzt nicht für alle faul.
Saurabh Tiwari
Der Beitrag wurde in Bezug auf das neueste Verhalten im Ruhezustand aktualisiert.
M Anouti
Es gab ein Update, in dem behauptet wurde, dass eifrig der Standard-Abruftyp für jedes Mapping ist, der in Kapitel 11.3 sowohl in der aktuellen 5.x- als auch in der neuen 6.x-Hibernate-Dokumentation widerlegt wird. Daher habe ich die Bearbeitung rückgängig gemacht. Außerdem ist es gegen die Empfehlung, keinen automatischen Eifer zu haben, da dies bedeuten würde, beim Abrufen eines einzelnen Objekts wahrscheinlich die gesamte Datenbank auszuwählen.
Alexander Rühl
51

Ich weiß, dass die Antworten zum Zeitpunkt des Fragens richtig waren - aber da sich Leute (wie ich in dieser Minute) immer noch fragen, warum sich ihr WildFly 10 anders verhält, möchte ich ein Update für den aktuellen Hibernate 5 geben .x Version:

Im Hibernate 5.2-Benutzerhandbuch wird dies in Kapitel 11.2 beschrieben. Anwenden von Abrufstrategien :

Die Empfehlung für den Ruhezustand lautet, alle Assoziationen statisch als faul zu markieren und dynamische Abrufstrategien für Eifer zu verwenden. Dies steht leider im Widerspruch zur JPA-Spezifikation, die definiert, dass alle Eins-zu-Eins- und Viele-zu-Eins-Assoziationen standardmäßig eifrig abgerufen werden sollten . Hibernate als JPA-Anbieter berücksichtigt diesen Standard.

Hibernate verhält sich also auch wie Ashish Agarwal, wie oben für JPA angegeben:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

(siehe JPA 2.1 Spec )

Alexander Rühl
quelle
Und was ist, wenn wir den nativen Ruhezustand anstelle von JPA impl verwenden, verhält es sich genauso?
jMounir
@jMounir: Nun, das habe ich nicht versucht, aber da Hibernate angibt, dass es sich wie in JPA definiert verhält, sehe ich nicht, warum sich das unterscheiden würde, wenn Hibernate für sich selbst verwendet wird. In beiden Fällen kann die Standardstrategie überschrieben werden.
Alexander Rühl
15

Um Ihre Frage zu beantworten, ist Hibernate eine Implementierung des JPA-Standards. Der Ruhezustand hat seine eigenen Funktionsmängel, jedoch gemäß den Hibernate-Dokumenten

Standardmäßig verwendet Hibernate das verzögerte Abrufen von Auswahlen für Sammlungen und das verzögerte Abrufen von Proxys für einwertige Zuordnungen. Diese Standardeinstellungen sind für die meisten Zuordnungen in den meisten Anwendungen sinnvoll.

Daher lädt der Ruhezustand jedes Objekt immer mit einer verzögerten Abrufstrategie, unabhängig davon, welche Art von Beziehung Sie deklariert haben. Es wird ein verzögerter Proxy (der nicht initialisiert, aber nicht null sein sollte) für ein einzelnes Objekt in einer Eins-zu-Eins- oder Viele-zu-Eins-Beziehung und eine Null-Sammlung verwendet, die beim Versuch, darauf zuzugreifen, mit Werten hydratisiert wird .

Es versteht sich, dass der Ruhezustand nur dann versucht, diese Objekte mit Werten zu füllen, wenn Sie versuchen, auf das Objekt zuzugreifen, es sei denn, Sie geben dies an fetchType.EAGER.

JamesENL
quelle
0

Für einwertige Zuordnungen, dh Eins-zu-Eins und Viele-zu-Eins: -
Standard Lazy = Proxy
Proxy Lazy Loading : - Dies impliziert, dass ein Proxy-Objekt Ihrer zugeordneten Entität geladen wird. Dies bedeutet, dass nur die ID, die die beiden Entitäten verbindet, für das Proxy-Objekt der zugeordneten Entität geladen wird.
Beispiel: A und B sind zwei Einheiten mit vielen zu einer Assoziation. dh: Es kann mehrere A für jedes B geben. Jedes Objekt von A enthält eine Referenz von B.
`

public class A{
    int aid;
    //some other A parameters;
    B b;
}
public class B{
    int bid;
     //some other B parameters;
}

`
Die Beziehung A enthält Spalten (Hilfe, Gebot, ... andere Spalten der Entität A).
Die Beziehung B enthält Spalten (Gebot, ... andere Spalten der Entität B)

Proxy impliziert, dass beim Abrufen von A nur die ID für B abgerufen und in einem Proxy-Objekt von B gespeichert wird, das nur die ID enthält. Das Proxy-Objekt von B ist ein Objekt einer Proxy-Klasse, die eine Unterklasse von B mit nur minimalen Feldern ist. Da das Gebot bereits Teil der Beziehung A ist, muss keine Abfrage ausgelöst werden, um das Gebot aus der Beziehung B zu erhalten. Andere Attribute der Entität B werden nur dann träge geladen, wenn auf ein anderes Feld als das Gebot zugegriffen wird.

Für Sammlungen, dh Viele-zu-Viele und Eins-zu-Viele: -
Standard Lazy = true


Bitte beachten Sie auch, dass die Abrufstrategie (Auswählen, Verbinden usw.) Lazy überschreiben kann. dh: Wenn faul = 'true' und fetch = 'join', werden beim Abrufen von A auch B oder Bs abgerufen (bei Sammlungen). Sie können den Grund bekommen, wenn Sie darüber nachdenken.
Der Standardabruf für eine einwertige Zuordnung ist "Join".
Der Standardabruf für Sammlungen ist "Auswählen". Bitte überprüfen Sie die letzten beiden Zeilen. Ich habe das logisch abgeleitet.

Jijo Mathew
quelle