session.get()とsession.load()の違い

多くの場合、Hibernateの開発者は session.get() session load() を混在させることに気付くでしょう。何が違うのでしょうか?

session.get()とsession.load()の違い

実際には、両方の関数は、もちろん、異なるメカニズムを使用してオブジェクトを取得するために使用されます。

1. session.load()

データベース。 Hibernateでは、プロキシは与えられた識別子の値を持つオブジェクトであり、そのプロパティはまだ初期化されていません。一時的な擬似オブジェクトのように見えます。

  • 行が見つからない場合は、 ObjectNotFoundException がスローされます。

2. session.get()

  • 常に** データベースにヒットし、実際のオブジェクト、オブジェクト

プロキシではなくデータベースの行を表します。

  • 行が見つからない場合は、 null を返します。

パフォーマンスについてです

Hibernateは何らかの理由で何かを作成しますが、アソシエーションを行うときには、データベースからオブジェクト(永続インスタンス)を取得し、それを他のオブジェクトへの参照として割り当て、関係を維持するのが普通です。 session.load() をどのような状況で使うべきかを理解するためのいくつかの例を見てみましょう。

1. session.get()

たとえば、Stockアプリケーションでは、StockとStockTransactionsには「1対多」の関係があります。株式取引を保存するには、以下のように宣言するのが一般的です

           Stock stock = (Stock)session.get(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
          //set stockTransactions detail
           stockTransactions.setStock(stock);
           session.save(stockTransactions);

出力

Hibernate:
    select ... from mkyong.stock stock0__
    where stock0__.STOCK__ID=?
Hibernate:
    insert into mkyong.stock__transaction (...)
    values (?, ?, ?, ?, ?, ?)

session.get()では、HibernateがデータベースにアクセスしてStockオブジェクトを取得し、StockTransactionへの参照として配置します。しかし、この保存プロセスは非常に高い需要であり、毎時千または百万件のトランザクションが存在する可能性があります。ストック・オブジェクトを検索するためにデータベースをヒットする必要があると思いますか?結局のところ、StockTransactionへの参照としてStockのIdが必要なだけです。

2. session.load()

上記のシナリオでは、 session.load() はあなたの良い解決策になります。例を見てみましょう。

           Stock stock = (Stock)session.load(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
          //set stockTransactions detail
           stockTransactions.setStock(stock);
           session.save(stockTransactions);

出力

Hibernate:
    insert into mkyong.stock__transaction (...)
    values (?, ?, ?, ?, ?, ?)

session.load()では、HibernateはStockオブジェクトを取得するためにデータベースにヒットしません(出力内のselectステートメントはありません)。Stockプロキシオブジェクト - 指定された識別値を持つ擬似オブジェクトを返します。このシナリオでは、プロキシオブジェクトは、株式取引レコードを保存するのに十分です。

例外

例外の場合は、例を参照してください

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());

指定されたID値を持つプロキシオブジェクトが常に返されます。たとえID値がデータベースに存在しなくても。ただし、データベースからプロパティを取得してプロキシを初期化しようとすると、selectステートメントでデータベースにヒットします。行が見つからない場合は、 ObjectNotFoundException がスローされます。

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.mkyong.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

ID値がデータベースに見つからない場合、常にNULLが戻されます。

結論

常に正しい解決策はありません。間にある差異を把握し、アプリケーションでどの方法が最も適切かを判断する必要があります。

前の投稿:Struts 2でHttpServletResponseを取得する方法
次の投稿:Java 8 - TemporalAdjustersの例