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

是的,您需要会话管理。但是,您可以在单个事务/会话中执行多个操作/查询。我建议从每个请求(如果您正在创建 Web 服务器)、作业等开始一个事务,并根据需要增加事务的粒度。

如果您想避免使用 Spring,那么这仍然可以通过方面轻松完成,但是您很快就会重复 Spring 所做的很多工作。

于 2012-10-12T17:28:33.780 回答
0

> 我在 JPA 中听说,CriteriaQuery(与 Criteria 相对)不需要主动事务管理。

这是正确的。

如果您将代码更改为标准 JPA,则不会强制在事务中运行任何查询 - 前提是您正在选择实体(而不是插入/更新/删除)并且没有在查询上设置 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 回答