【问题标题】:Can the same CriteriaBuilder (JPA 2) instance be used to create multiple queries?可以使用同一个 CriteriaBuilder (JPA 2) 实例来创建多个查询吗?
【发布时间】:2011-02-21 06:54:57
【问题描述】:

这似乎是一个非常简单的问题,但我还没有找到明确的答案。我有一个 DAO 类,它自然地使用标准查询来查询数据库。所以我想知道使用相同的 CriteriaBuilder 实现来创建不同的查询是否安全,或者我是否必须为每个查询创建新的 CriteriaBuilder 实例。以下代码示例应该说明我想做什么:

public class DAO() {  
    CriteriaBuilder cb = null;

    public DAO() {
        cb = getEntityManager().getCriteriaBuilder();
    }

    public List<String> getNames() {
        CriteriaQuery<String> nameSearch = cb.createQuery(String.class);
        ...
    }

    public List<Address> getAddresses(String name) {
        CriteriaQuery<Address> nameSearch = cb.createQuery(Address.class);
        ...
    }
}

这样做可以吗?

【问题讨论】:

    标签: java jpa criteria-api jpa-2.0


    【解决方案1】:

    有趣的问题。我会说“当然,这就是标准查询的全部意义所在”,但我在这里找不到一个词来支持这一点:http://java.sun.com/javaee/6/docs/tutorial/doc/gjivm.html

    但是:如果它们不可重用,那将意味着实体管理器实际上会修改它们,这将是糟糕的 api 设计。所以:我希望它们可以重复使用,但我不能保证

    【讨论】:

      【解决方案2】:

      阅读 JPA 2.0 规范 (JSR 317) 的 3.1.1 EntityManager 接口 部分中的 javadoc:

      /**
       * Return an instance of CriteriaBuilder for the creation of
       * CriteriaQuery objects.
       * @return CriteriaBuilder instance
       * @throws IllegalStateException if the entity manager has
       *         been closed
       */
      public CriteriaBuilder getCriteriaBuilder();
      

      然后是这条评论:

      Query, TypedQuery, CriteriaBuilderMetamodelEntityTransaction 获得的对象 来自实体经理的有效而 该实体管理器已打开。

      以及6.5 构造条件查询部分

      CriteriaBuilder 接口是 用于构造CriteriaQuery 对象。 CriteriaBuilder 实现是通过访问 getCriteriaBuilder 的方法 EntityManagerEntityManagerFactory接口。

      我希望能够重用单个CriteriaBuilder 来为实体管理器的生命周期创建许多查询。但这是我的解释。但是,我最初的测试似乎证实了这并没有什么问题(相反确实很可怕)。

      【讨论】:

      • 谢谢帕斯卡。你的解释听起来很可靠。这对我帮助很大。
      【解决方案3】:

      这是安全的。

      您可以从 EntityManagerFactory 获取 CriteriaBuilder。 在休眠实现中,criteriaBuilder 是 EntityManagerFactory 的实例字段。所以在传统情况下,没有风险。

      【讨论】:

        【解决方案4】:

        当您启动查询时,Eclipse Link 会随机生成错误(EclipseLink-6089、org.eclipse.persistence.exceptions.QueryException)(有时有效,有时无效),然后在执行第一个查询之前生成另一个错误。详情请见Stack OverflowJBoss issues

        如果您一个一个地运行查询或计划使用 Hibernate,那么重用 CriteriaBuilder 没有问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-02
          • 2014-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多