与JPA CriteriaBuilder合并所有和总和

与JPA CriteriaBuilder合并所有和总和,jpa,sum,union,criteria-api,Jpa,Sum,Union,Criteria Api,我正在尝试将本机SQL查询转换为使用JPA2.0中的CriteriaAPI。我在Google上找到了很多CriteriaAPI示例,但是我真的很难把所有的部分整合起来。我希望一个更有经验的人能帮助我。本机查询如下所示: select sum(amount) from firstTable, secondTable where firstTable.id = secondTable.id and amount <> 0

我正在尝试将本机SQL查询转换为使用JPA2.0中的CriteriaAPI。我在Google上找到了很多CriteriaAPI示例,但是我真的很难把所有的部分整合起来。我希望一个更有经验的人能帮助我。本机查询如下所示:

select 
    sum(amount) from firstTable, secondTable 
        where firstTable.id = secondTable.id 
            and amount <> 0 
            and firstTable.id = ?
union all
select 
    sum(amount) from firstTable, thirdTable 
        where firstTable.id = thirdTable.id 
            and amount <> 0 
            and firstTable.id = ?
原始查询结果集正在返回BigDecimal对象的列表


谢谢大家!

JPA不支持UNION,或者使用本机SQL查询,或者执行两个查询。

很抱歉,下面的示例不是UNION,而是join

我会考虑使用多个根的查询。< /P> 这是Hibernate开发者指南中的一个练习,代码与JPA2.0兼容

条件查询可以定义多个根,其效果是在新添加的根和其他根之间创建笛卡尔乘积。下面是一个匹配所有单身男性和所有单身女性的示例:


如果您需要Union All,那么在我看来,两个实体是将继承应用于它们的候选对象。

正如Marcin指出的,继承是可能的,至少在特殊情况下是可能的

如果您可以使用hibernate中提供的可选表每类继承策略使查询的实体从一个继承到另一个,但是有一些限制-不能使用IDENTITY和AUTO,如果要在查询中显示的字段在两个实体中具有相同的名称,则可以通过查询父实体来合并这两个实体

例如,若实体类子级从实体类父级扩展而来,且两者都具有字段名,则查询将为:

从父p中选择p.name

若要仅选择父实体的名称,请添加类型为的条件

从父p中选择p.name,其中TYPEp=Parent


如果修改实体以从一个实体继承另一个实体是不合适的,您可以通过继承创建特殊的实体,这当然是此查询的原因,因为可以为同一个表创建多个实体。但您可能觉得这样做不合理。

您知道为什么不支持UNION吗?EclipseLink支持UNION select子句在这里看起来如何?我正在使用criteriaBuilder.construct获取所选列。to@user613114:我已经好几年没有使用ORM和Java了,但我会尝试回答这个问题。上面的例子将给出单身男人和单身女人的所有可能组合。SQL查询将如下所示:从人员a中选择a.name b.name,其中a.gender='male'和b.gender='female'和a.status=single和b.status=single我有同样的问题要解决,通过这个我可以使联合产生与JPA/JPQL联合的效果,但代价是子查询和或的性能不佳。
CriteriaQuery query = builder.createQuery();
Root<Person> men = query.from( Person.class );
Root<Person> women = query.from( Person.class );
Predicate menRestriction = builder.and(
        builder.equal( men.get( Person_.gender ), Gender.MALE ),
        builder.equal( men.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE )
);
Predicate womenRestriction = builder.and(
        builder.equal( women.get( Person_.gender ), Gender.FEMALE ),
        builder.equal( women.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE )
);
query.where( builder.and( menRestriction, womenRestriction ) )