Proxy im Ruhezustand der load () - Methode

Proxy in Ruhezustand load () Methode

1. Überblick

In diesem Tutorial sehen wir, was ein Proxy im Kontext derload()-Methode von Hibernate ist.

Für Leser, die neu im Ruhezustand sind, sollten Sie sich zuerst mitbasicsvertraut machen.

2. Eine kurze Einführung in Proxies und die Methode vonload()

By definition, a proxy is “a function authorized to act as the deputy or substitute for another”.

Dies gilt für den Ruhezustand, wenn wirSession.load() aufrufen, um ein so genanntesuninitialized proxy für unsere gewünschte Entitätsklasse zu erstellen.

Einfach ausgedrückt, Hibernate unterteilt unsere Entitätsklasse unter Verwendung derCGLib-Bibliothek. Mit Ausnahme der@Id-Methode delegiert die Proxy-Implementierung alle anderen Eigenschaftsmethoden an die Hibernate-Sitzung, um die Instanz zu füllen.

public class HibernateProxy extends MyEntity {
    private MyEntity target;

    public String getFirstName() {
        if (target == null) {
            target = readFromDatabase();
        }
        return target.getFirstName();
    }
}

Diese Unterklasse wird zurückgegeben, anstatt die Datenbank direkt abzufragen.

Sobald eine der Entitätsmethoden aufgerufen wird, wird die Entität geladen und wird zu diesem Zeitpunkt zuinitialized proxy.

3. Proxies und Lazyloadingen

3.1. Eine einzelne Einheit

Denken wir anEmployee als Entität. Zunächst gehen wir davon aus, dass es keine Beziehung zu anderen Tabellen gibt.

Wenn wirSession.load() verwenden, um einEmployee zu instanziieren:

Employee albert = session.load(Employee.class, new Long(1));

Anschließend erstellt der Ruhezustand einen nicht initialisierten Proxy vonEmployee. It will contain the ID that we gave it but otherwise will have no other values because we haven’t hit the database yet.

Sobald wir jedoch eine Methode füralbert aufrufen:

String firstName = albert.getFirstName();

Anschließend fragt Hibernate die Datenbanktabelleemployeenach einer Entität mit dem Primärschlüssel 1 ab und fülltalbert mit seinen Eigenschaften aus der entsprechenden Zeile.

Wenn keine Zeile gefunden wird, löst Hibernate einObjectNotFoundException aus.

3.2. Eins-zu-viele-Beziehungen

Erstellen wir nun auch eineCompany -Sentität, wobei einCompany vieleEmployees: hat

public class Company {
    private String name;
    private Set employees;
}

Wenn wir diesmalSession.load() on der Firma verwenden:

Company bizco = session.load(Company.class, new Long(1));
String name = bizco.getName();

Dann werden die Immobilien des Unternehmens wie zuvor gefüllt, außer dass die Anzahl der Mitarbeiter nur ein bisschen anders ist.

Wir haben nur die Unternehmenszeile abgefragt, aber der Proxy lässt den Mitarbeiter in Ruhe, bis wir abhängig von der AbrufstrategiegetEmployees aufrufen.

3.3. Viele-zu-Eins-Beziehungen

Ähnlich verhält es sich in umgekehrter Richtung:

public class Employee {
    private String firstName;
    private Company workplace;
}

Wenn wir wiederload() verwenden:

Employee bob = session.load(Employee.class, new Long(2));
String firstName = bob.getFirstName();

bob will wird jetzt initialisiert, undworkplace wird nun abhängig von der Abrufstrategie als nicht initialisierter Proxy festgelegt.

4. Lazy-ish Laden

load() gibt uns nicht immer einen nicht initialisierten Proxy. Tatsächlich erinnert uns dasSession java doc (Hervorhebung hinzugefügt):

Diese Methodemightgibt eine Proxy-Instanz zurück, die bei Bedarf initialisiert wird, wenn auf eine Methode ohne Kennung zugegriffen wird.

Ein einfaches Beispiel dafür, wann dies passieren kann, ist die Chargengröße.

Nehmen wir an, wir verwenden@BatchSize für unsereEmployee -Sentität:

@Entity
@BatchSize(size=5)
class Employee {
    // ...
}

Und diesmal haben wir drei Mitarbeiter:

Employee catherine = session.load(Employee.class, new Long(3));
Employee darrell = session.load(Employee.class, new Long(4));
Employee emma = session.load(Employee.class, new Long(5));

Wenn wirgetFirstName oncatherine nennen:

String cathy = catherine.getFirstName();

Dann kann Hibernate tatsächlich entscheiden, alle drei Mitarbeiter gleichzeitig zu laden und alle drei in initialisierte Proxys umzuwandeln.

Und dann, wenn wir den Vornamen vondarrellaufrufen:

String darrell = darrell.getFirstName();

DannHibernate doesn’t hit the database at all.

5. Eifriges Laden

5.1. Verwenden vonget()

Wir können Proxys auch vollständig umgehen und Hibernate bitten, die reale Sache mitSession.get() zu laden:

Employee finnigan = session.get(Employee.class, new Long(6));

Dadurch wird die Datenbank sofort aufgerufen, anstatt einen Proxy zurückzugeben.

Und tatsächlich wird anstelle vonObjectNotFoundExceptionnull zurückgegeben, wennfinnigan nicht vorhanden ist.

5.2. Auswirkungen auf die Leistung

Währendget() praktisch ist, kannload() in der Datenbank leichter sein.

Nehmen wir zum Beispiel an,gerald is wird für ein neues Unternehmen arbeiten:

Employee gerald = session.get(Employee.class, new Long(7));
Company worldco = (Company) session.load(Company.class, new Long(2));
employee.setCompany(worldco);
session.save(employee);

Da wir wissen, dass wir in dieser Situation nur denemployee -Srecord ändern werden, ist,, derload() fürCompany  nennt, sinnvoll.

Wenn wirget() aufCompany aufgerufen hätten, hätten wir alle Daten unnötig aus der Datenbank geladen.

6. Fazit

In diesem Artikel haben wir kurz erfahren, wie die Proxys vonHibernatefunktionieren und wie sich dies auf die Methode vonloadmit Entitäten und deren Beziehungen auswirkt.

Außerdem haben wir uns kurz angesehen, wie sichload() vonget(). unterscheidet

Wie üblich ist der vollständige Quellcode, der dem Lernprogramm beiliegt,over on GitHub. verfügbar