JPA Criteria API – 如何添加JOIN子句(作为一般句子)

我试图动态构造查询,我的下一个目标是添加JOIN子句(我不知道如何使用API​​)。

例如,到目前为止,这段代码对我有用:

... Class baseClass; ... CriteriaBuilder cb = JpaHandle.get().getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(this.baseClass); Root entity_ = cq.from(this.baseClass); Predicate restrictions = null; ... restrictions = cb.conjunction(); restrictions = cb.and(restrictions, entity_.get("id").in(this.listId)); ... cq.where(restrictions); ... Query qry = JpaHandle.get().createQuery(cq); 

(注意:JpaHandle来自wicket-JPA实现)

我的愿望是添加JOIN子句(尽可能通用)!

我在类中有特定的注释(this.baseClass)

例如 :

 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "assay_id", nullable = false) 

那么,在标准JPA中有没有这样的方法呢? (注意:这不编译)

这是一个实际的失败方法:

 ... Join experimentAssays = entity_.join( entity_.get("assay_id") ); 

或者像那样:

 ... CriteriaQuery q = cb.createQuery(Customer.class); Root c = q.from(Customer.class); SetJoin o = c.join(Customer_.orders); 

对我来说,如果它可能更加通用,它会很棒……:

 ... Join joinClause = entity_join(entity_.get("assay_id"), entity2_.get("id")); 

当然,我在类中有特定的注释(this.baseClass)

感谢您的时间。 我会感谢各种评论!

也许从第23章 – 使用Criteria API创建 Java EE 6教程查询的以下摘录将会有所启发(实际上,我建议阅读整个第23章):

使用连接查询关系

对于导航到相关实体类的查询,查询必须通过调用查询根对象或另一个join对象上的一个From.join方法来定义与相关实体的join 。 连接方法类似于JPQL中的JOIN关键字。

连接的目标使用EntityType类型的Metamodel类来指定已连接实体的持久字段或属性。

join方法返回Join类型的对象,其中X是源实体, Y是连接的目标。

示例23-10加入查询

 CriteriaQuery cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel(); EntityType Pet_ = m.entity(Pet.class); Root pet = cq.from(Pet.class); Join owner = pet.join(Pet_.owners); 

可以将连接链接在一起以导航到目标实体的相关实体,而无需为每个连接创建Join实例。

示例23-11在查询中将联接链接在一起

 CriteriaQuery cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel(); EntityType Pet_ = m.entity(Pet.class); EntityType Owner_ = m.entity(Owner.class); Root pet = cq.from(Pet.class); Join address = cq.join(Pet_.owners).join(Owner_.addresses); 

话虽如此,我还有一些补充意见:

首先,代码中的以下行:

 Root entity_ = cq.from(this.baseClass); 

让我觉得你错过了静态元模型类部分。 引用示例中的元模型类(如Pet_用于描述持久类的元信息 。 它们通常使用注释处理器( 规范元模型类 )生成,或者可以由开发人员编写( 非规范元模型 )。 但是你的语法看起来很奇怪,我想你正试图模仿你错过的东西。

其次,我真的认为你应该忘记这个assay_id外键,你在这里走错路。 你真的需要开始思考对象和关联,而不是表和列。

第三,我并不确定通过添加JOIN子句尽可能通用以及你的对象模型看起来完全理解你的意思,因为你没有提供它(见前一点)。 因此,更准确地回答你的问题是不可能的。

总而言之,我认为您需要阅读更多有关JPA 2.0 Criteria和Metamodel API的内容,我热烈推荐以下资源作为起点。

也可以看看

  • JPA 2.0规范中的6.2.1静态元模型类
  • JPA 2.0中的动态,类型安全查询
  • 使用Criteria API和Metamodel API创建基本类型安全查询

相关问题

  • 如何生成JPA 2.0元模型?

实际上,如果您的注释正确,则不必处理静态元模型。

你可以用这个:

 CriteriaQuery cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel(); EntityType petMetaModel = m.entity(Pet.class); Root pet = cq.from(Pet.class); Join owner = pet.join(petMetaModel.getSet("owners", Owner.class)); 

您不需要学习JPA。 您可以使用我的简单标准JPA2( https://sourceforge.net/projects/easy-criteria/files/ )。 这是一个例子

 CriteriaComposer petCriteria CriteriaComposer.from(Pet.class). where(Pet_.type, EQUAL, "Cat").join(Pet_.owner).where(Ower_.name,EQUAL, "foo"); List result = CriteriaProcessor.findAllEntiry(petCriteria); 

要么

 List result = CriteriaProcessor.findAllTuple(petCriteria); 

警告! Sun JPA 2示例中存在大量错误,并且Pascal的答案中出现了粘贴的内容。 请查阅这篇文章 。

这篇文章和Sun Java EE 6 JPA 2的例子确实阻碍了我对JPA 2的理解。在浏览了Hibernate和OpenJPA手册并认为我对JPA 2有了很好的理解后,我在回到这篇文章后仍感到困惑。 。