【问题标题】:Do you need to commit/close a session after doing a Criteria query in Hibernate?在 Hibernate 中执行 Criteria 查询后是否需要提交/关闭会话?
【发布时间】:2012-10-12 16:32:00
【问题描述】:

我的代码如下所示:

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)不需要主动事务管理。

【问题讨论】:

  • 根据Hibernate documentation,事务绝不是可选的。您应该在事务中完成所有工作并在最后提交。
  • 谢谢。当我看到所有这些带有不显示代码会话部分的 Criteria 示例时,我感到很困惑。
  • 这可能是因为该部分是标准样板并且是隐含的。
  • @SomeNewbie:使用 Spring 及其声明式会话和事务管理,您将永远不必打开和关闭会话,以及显式地开始和结束事务。
  • @SomeNewbie:选择其中任何一个,但一定要使用允许声明式事务和会话管理的东西。

标签: java hibernate session orm criteria


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      相关资源
      最近更新 更多