Subquery in select clause with JPA Criteria API

后端 未结 4 1018
野性不改
野性不改 2020-12-13 05:25

I\'m trying, as in title, to insert a subquery in select clause like in this simple SQL:

SELECT id, name, (select cou         


        
相关标签:
4条回答
  • 2020-12-13 06:04

    You need to coalesce your subquery result:

    Expression<ResultType> expression = criterioaBuilder.coalesce(subquery, criteriaBuilder.literal((ResultType) defaultResult);
    query.select(expression);
    
    0 讨论(0)
  • 2020-12-13 06:07

    JPA does not support sub-queries in the select clause.

    You need to either change your query so as not to use require the sub-query in the select clause, execute multiple queries, or use a native SQL query.

    0 讨论(0)
  • 2020-12-13 06:18

    JPA now supports sub-queries in the select clause.

    EDIT:
    JPA 2.1 JPQL BNF supports sub-queries in select clause even if it's not required. As far as I know Eclipselink Supports this and Hibernate too (tested in 5.1).

    0 讨论(0)
  • 2020-12-13 06:23

    It is supported in JPA 2.1 and Hibernate 5.0. You just had to add getSelection() to the subquery argument in the multiselect of the main query.

    c.multiselect(item.get("id"),item.get("nome"), scount.getSelection());
    

    Take a look at this working example:

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<NotificationInfo> cq = builder.createQuery(NotificationInfo.class); //wrapper class
    Root<Notification> n = cq.from(Notification.class); //root entity
    
    //Subquery
    Subquery<Long> sqSent = cq.subquery(Long.class);
    Root<NotificationUser> sqSentNU = sqSent.from(NotificationUser.class);
    sqSent.select(builder.count(sqSentNU));
    sqSent.where(
            builder.equal(sqSentNU.get(NotificationUser_.notification), n),  //join subquery with main query
            builder.isNotNull(sqSentNU.get(NotificationUser_.sendDate))
    );
    
    cq.select(
        builder.construct(
                NotificationInfo.class,
                n.get(Notification_.idNotification),
                n.get(Notification_.creationDate),
                n.get(Notification_.suspendedDate),
                n.get(Notification_.type),
                n.get(Notification_.title),
                n.get(Notification_.description),
                sqSent.getSelection()
        )
    );
    em.createQuery(cq).getResultList();
    
    0 讨论(0)
提交回复
热议问题