是否可以使用相同的CriteriaBuilder(JPA 2)实例创建多个查询?

时间:2010-05-19 09:02:02

标签: java jpa criteria-api jpa-2.0

这似乎是一个非常简单的问题,但我还没有找到确定的答案。我有一个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);
        ...
    }
}

这样做可以吗?

4 个答案:

答案 0 :(得分:12)

阅读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();

此评论刚刚发布:

  

QueryTypedQuery,   CriteriaBuilderMetamodel和。{   获得EntityTransaction个对象   来自实体经理的有效期   该实体经理是开放的。

部分 6.5构建标准查询

  

CriteriaBuilder界面是   用于构建CriteriaQuery   对象。 CriteriaBuilder   实现是通过   getCriteriaBuilder方法   EntityManager或   EntityManagerFactory界面。

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

这是安全的。

您可以从EntityManagerFactory获取CriteriaBuilder。 在hibernate实现中,criteriaBuilder是EntityManagerFactory的实例字段。所以在传统案例中,没有风险。

答案 3 :(得分:1)

Eclipse Link在您启动查询时以随机方式(有时它可以运行,有时不运行)生成错误(EclipseLink-6089,org.eclipse.persistence.exceptions.QueryException),然后在执行第一个查询之前生成另一个错误。有关详细信息,请参阅Stack OverflowJBoss issues

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