Unterschied zwischen session.get () und session.load ()
Oft werden Sie feststellen, dass Entwickler im Ruhezustand die Verwendung vonsession.get() undsession load() mischen. Fragen Sie sich, was anders ist und wann Sie eines davon verwenden sollten?
Unterschied zwischen session.get () und session.load ()
Eigentlich werden beide Funktionen verwendet, um ein Objekt mit unterschiedlichen Mechanismen abzurufen.
1. session.load()
-
Es wird immer ein "proxy" (Ruhezustand) zurückgegeben, ohne die Datenbank zu treffen. Im Ruhezustand ist Proxy ein Objekt mit dem angegebenen Bezeichnerwert, dessen Eigenschaften noch nicht initialisiert sind. Es sieht nur aus wie ein temporäres, gefälschtes Objekt.
-
Wenn keine Zeile gefunden wird, wird einObjectNotFoundException ausgelöst.
2. session.get()
-
Es ist immerhit the database und gibt das reale Objekt zurück, ein Objekt, das die Datenbankzeile darstellt, nicht den Proxy.
-
Wenn keine Zeile gefunden wird, wirdnull zurückgegeben.
Es geht um Leistung
Wenn Sie im Ruhezustand eine Verknüpfung erstellen, ist es aus bestimmten Gründen normal, ein Objekt (persistente Instanz) aus der Datenbank abzurufen und es als Verweis auf ein anderes Objekt zuzuweisen, um die Beziehung aufrechtzuerhalten. Lassen Sie uns einige Beispiele durchgehen, um zu verstehen, in welcher Situation Siesession.load() verwenden sollten.
1. session.get()
Zum Beispiel sollten in einer Aktienanwendung Stock und StockTransactions eine Eins-zu-Viele-Beziehung haben. Wenn Sie eine Aktienbuchung speichern möchten, ist es üblich, Folgendes zu deklarieren
Stock stock = (Stock)session.get(Stock.class, new Integer(2)); StockTransaction stockTransactions = new StockTransaction(); //set stockTransactions detail stockTransactions.setStock(stock); session.save(stockTransactions);
Ausgabe
Hibernate: select ... from example.stock stock0_ where stock0_.STOCK_ID=? Hibernate: insert into example.stock_transaction (...) values (?, ?, ?, ?, ?, ?)
In session.get () schlägt Hibernate auf die Datenbank zu, um das Stock-Objekt abzurufen und als Referenz auf StockTransaction zu setzen. Dieser Speichervorgang ist jedoch sehr gefragt. Möglicherweise gibt es Tausende oder Millionen Transaktionen pro Stunde. Glauben Sie, dass dies erforderlich ist, um die Datenbank abzurufen und das Objekt Stock abzurufen. Alles, was einen Aktientransaktionsdatensatz sichert? Schließlich benötigen Sie nur die Stock’s Id als Referenz für StockTransaction.
2. session.load()
Im obigen Szenario istsession.load() Ihre gute Lösung. Sehen wir uns das Beispiel an:
Stock stock = (Stock)session.load(Stock.class, new Integer(2)); StockTransaction stockTransactions = new StockTransaction(); //set stockTransactions detail stockTransactions.setStock(stock); session.save(stockTransactions);
Ausgabe
Hibernate: insert into example.stock_transaction (...) values (?, ?, ?, ?, ?, ?)
In session.load () wird Hibernate die Datenbank nicht erreichen (keine Select-Anweisung in der Ausgabe), um das Stock-Objekt abzurufen. Es wird ein Stock-Proxy-Objekt zurückgegeben - ein gefälschtes Objekt mit einem bestimmten Identifizierungswert. In diesem Szenario reicht ein Proxy-Objekt aus, um einen Aktientransaktionsdatensatz zu speichern.
Ausnahme
In Ausnahmefällen siehe Beispiele
session.load()
Stock stock = (Stock)session.load(Stock.class, new Integer(100)); //proxy //initialize proxy, no row for id 100, throw ObjectNotFoundException System.out.println(stock.getStockCode());
Es wird immer ein Proxy-Objekt mit dem angegebenen Identitätswert zurückgegeben, auch wenn der Identitätswert nicht in der Datenbank vorhanden ist. Wenn Sie jedoch versuchen, einen Proxy zu initialisieren, indem Sie dessen Eigenschaften aus der Datenbank abrufen, wird die Datenbank mit der Anweisung select aufgerufen. Wenn keine Zeile gefunden wird, wird einObjectNotFoundException geworfen.
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.example.common.Stock#100]
session.get()
//return null if not found Stock stock = (Stock)session.get(Stock.class, new Integer(100)); System.out.println(stock.getStockCode()); //java.lang.NullPointerException
Es wird immer null zurückgegeben, wenn der Identitätswert nicht in der Datenbank gefunden wird.
Fazit
Es gibt keine immer richtige Lösung. Sie müssen den Unterschied zwischen den beiden verstehen und entscheiden, welche Methode für Ihre Anwendung am besten geeignet ist.