> 我在 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 不是)、标准的、面向对象的、在初始化时编译的,因此速度很快。:-)