Java JPA2+标准API-定义子查询

Java JPA2+标准API-定义子查询,java,hibernate,subquery,jpa-2.0,criteria-api,Java,Hibernate,Subquery,Jpa 2.0,Criteria Api,我尝试将sql查询转换为CriteriaAPI,但迄今为止没有成功。我可以创建两个单独的查询,返回所需的值,但我不知道如何在单个查询中组合它们 以下是有效的sql语句: select company.*, ticketcount.counter from company join (select company, COUNT(*) as counter from ticket where state<16 group by company) ticketcount on comp

我尝试将sql查询转换为CriteriaAPI,但迄今为止没有成功。我可以创建两个单独的查询,返回所需的值,但我不知道如何在单个查询中组合它们

以下是有效的sql语句:

select company.*, ticketcount.counter from company
    join 
(select company, COUNT(*) as counter from ticket where state<16 group by company) ticketcount
on company.compid = ticketcount.company;
那么,有人知道如何让它工作吗

更新

多谢各位。我按照您的建议更改了条件查询。我只需要在末尾添加一个循环来获取我想要的信息

List<intCompany> result = em.createQuery(cq).getResultList();
List<Company> cresult = new ArrayList();
    for(intCompany ic: result){
        ic.comp.setOpentickets(ic.opentickets.intValue());
        cresult.add(ic.comp);
    }
return cresult;
也许将原始sql转换为CriteriaAPI是不可能的

另一个更新

我发现我必须将原来的sql表达式更改为

select company.*, ticketcount.counter from company
    left join 
(select company, COUNT(*) as counter from ticket where state<16 group by company) ticketcount
on company.compid = ticketcount.company;
否则我不会得到票证表中没有条目的公司


那么还有其他建议吗?

你几乎什么都做了

//---//
CriteriaBuilder cb = em.getCriteriaBuilder();
//Your Wrapper class constructor must match with multiselect arguments
CriteriaQuery<IntCompany> cq = cb.createQuery(IntCompany.class);
//Main table
final Root<Ticket> fromTicket= cq.from(Ticket.class);
//Join defined in Ticket Entity
final Path company = fromTicket.get("company");
//Data to select
cq.multiselect(cb.count(from), company);
//Grouping
cq.groupBy(company);
//Restrictions (I don't really understand what you're querying)
Predicate p = cb.lessThan(fromTicket.get("state"), 16);
//You can add more restrictions
// p = cb.and/or(p, ...);
cq.where(p);
List<IntCompany> results = entityManager.createQuery(cq).getResultList();

这应该可以像预期的那样工作。

我也有类似的问题。我的解决方案是使用左外连接

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Entity> query = cb.createQuery(Entity.class);
Root<Entity> root = query.from(Entity.class);

Join<Entity,ChildEntity> join = root.join(Entity_.children, JoinType.LEFT);
query.groupBy(root.get( Entity_.id ));
query.select(
  cb.construct(
    EntityDTO.class,
    root.get( Entity_.id ),
    root.get( Entity_.name ),
    cb.count(join)
));
静态模型:

@StaticMetamodel( Entity.class )
public class Entity_ {
    public static volatile SingularAttribute<Entity, Long> id;
    public static volatile SingularAttribute<Entity, String> name;
    ...
    public static volatile SetAttribute<Entity, ChildEntity> objects;
}
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Entity> query = cb.createQuery(Entity.class);
Root<Entity> root = query.from(Entity.class);

Join<Entity,ChildEntity> join = root.join(Entity_.children, JoinType.LEFT);
query.groupBy(root.get( Entity_.id ));
query.select(
  cb.construct(
    EntityDTO.class,
    root.get( Entity_.id ),
    root.get( Entity_.name ),
    cb.count(join)
));
@Entity
public class Entity {
    ...

    @OneToMany(targetEntity = ChildEntity.class, mappedBy = "parent", fetch = FetchType.LAZY, orphanRemoval = false)
    private Set<ChildEntity> objects;

    ...
}
@StaticMetamodel( Entity.class )
public class Entity_ {
    public static volatile SingularAttribute<Entity, Long> id;
    public static volatile SingularAttribute<Entity, String> name;
    ...
    public static volatile SetAttribute<Entity, ChildEntity> objects;
}