3

JPA/Eclipse TopLink の使用。

以下に示すように、(createNativeQuery を使用して) テーブルを更新しています。

Query query = em.createNativeQuery("UPDATE Products SET productName='" + p.getProductName() + "',productVendor='" + p.getProductVendor() + "',productDescription='" + p.getProductDescription() + "',quantityInStock=" + p.getQuantityInStock() + ",buyPrice =" + p.getBuyPrice() + ",msrp=" + p.getMsrp() + " WHERE productCode='" + p.getProductCode() + "'");
query.executeUpdate();

DB(MySQL)に更新が反映される

以下に示すように(createQueryを使用して)取得する場合:

Query query1 = em.createQuery("SELECT p from Products p where p.productCode='"+searchTerm+"'");
return query1.getResultList();

ただし、返される ResultList は常に更新前のデータです。しかし、createQuery の代わりに createNativeQuery を使用すると、最新の更新されたデータが返されます。createQuery メソッドで考えられるエラーは何ですか?

4

1 に答える 1

6

バッチ更新またはネイティブ クエリを使用すると、第 1 レベルのキャッシュがバイパスされます。Toplink は、第 1 レベルのキャッシュに既にあるエンティティが変更されたことを知る方法がありません。そのため、クエリが更新されたオブジェクトを返すためには、エンティティ マネージャーをクリアする必要があります。

しかし、おそらく最善の方法は、そもそもバッチ更新を避けることです。最初のクエリは、指定されたコードで製品をロードし、単純に Product エンティティを更新する JPQL クエリに置き換えることができます。更新クエリを保持したとしても、SQL ではなく JPQL で記述できます (ただし、問題は解決しません)。

最後に、クエリはパラメーターを使用してインジェクションを回避し、すべてが適切にエスケープされるようにする必要があります。

Query query1 = em.createQuery("SELECT p from Products p where p.productCode = :searchTerm);
query1.setParameter("searchTerm", searchTerm);
return query1.getResultList();
于 2011-11-27T08:39:01.593 に答える