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

2022-09-02 21:53:59

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

这样做可以吗?


答案 1

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

这个评论紧随其后:

从实体管理器获取的 、、、 和对象在该实体管理器处于打开状态时有效。QueryTypedQueryCriteriaBuilderMetamodelEntityTransaction

以及 6.5 构造条件查询部分

该接口用于构造对象。通过 或 接口的方法访问实现。CriteriaBuilderCriteriaQueryCriteriaBuildergetCriteriaBuilderEntityManagerEntityManagerFactory

我希望能够重用单个查询,以便在实体管理器的生存期内创建许多查询。但这就是我的解释。然而,我最初的测试似乎证实了这没有什么错(相反,这确实很可怕)。CriteriaBuilder


答案 2

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

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


推荐