4

次のようなコードがあります。

Session session = MySessionFactory.createSession();
session.beginTransaction();
Criteria cq = session.createCriteria(clazz);
// Do stuff.
List list = cq.list();
session.getTransaction().commit();
session.close();

beginTransaction()、commit()、および close() は実際に必要ですか?

JPA では、CriteriaQuery (Criteria とは対照的に) はアクティブなトランザクション管理を必要としないと聞きました。

4

2 に答える 2

1

はい、セッション管理が必要です。ただし、1 つのトランザクション/セッション内で複数の操作/クエリを実行できます。リクエスト (Web サーバーを作成している場合)、ジョブなどごとに 1 つのトランザクションから始めて、必要に応じてトランザクションの粒度を増やすことをお勧めします。

Spring を回避したい場合でも、これはアスペクトで簡単に実行できますが、Spring が行った多くの作業をすぐに繰り返すことになります。

于 2012-10-12T17:28:33.780 に答える
0

> JPA では、CriteriaQuery (Criteria とは対照的に) はアクティブなトランザクション管理を必要としないと聞きました。

そのとおりです。

コードを標準 JPA に変更すると、エンティティを選択し (INSERTING/UPDATING/DELETING ではなく)、クエリに LockMode を設定していなければ、トランザクション内で強制的に実行されるクエリはありません。

これが目的の JPQL である場合:

SELECT c
FROM Customer c JOIN c.orders o JOIN o.lineItems i
WHERE i.product.productType = 'printer'

標準的な JPA 基準のクエリ コードは次のようになります。

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Customer> cq = cb.createQuery(Customer.class);
Root<Customer> customer = cq.from(Customer.class);
Join<Customer, Order> order = customer.join(Customer_.orders); // or .join("orders")
Join<Order, Item> item = order.join(Order_.lineItems);         // or .join("lineItems")

ParameterExpression<String> p = cb.parameter(String.class, "prodType");
cq.select(customer)
  .where(cb.equal(item.get(Item_.product).get(Product_.productType), p));
// if you haven't generated JPA metamodel Customer_, Product_, etc, 
// can replace this with 
//  .where(cb.equal(item.get("product").get("productType"), p));


TypedQuery<Employee> tq = em.createQuery(cq);
q.setParameter("prodType", "printer");
return q.getResultList();

少し醜いですが、強く型付けされ (JPQL はそうではありません)、標準で、オブジェクト指向で、初期化時にコンパイルされるため高速です。:-)

于 2012-10-15T00:56:21.020 に答える