JPA Criteria Equivalent Query Subquery最大或最大

时间:2013-02-04 19:57:19

标签: jpa websphere criteria ejb-3.1 openjpa

此SQL查询完全执行所需的操作。我正在寻找相当于JPA标准的?基本上从一对多关系中获取设备实体和最佳(最大)GPS坐标

SELECT DISTINCT t0.DEVICE_I, t0.ACTIVE_S, t0.APP_CONFIG_I, t0.PREV_APP_CONFIG_I, 
t0.APP_CONFIG_CONFIRMED_S, t0.APP_CONFIG_RECEIPT_D, t0.APP_CONFIG_SENT_S, t0.CHANNEL_X, 
t0.CREATION_TS, t0.CREATION_USER_I, t0.DEST_QUEUE_C, t0.DIVISION_C, t0.LAN_IP_X, 
t0.LAST_UPDATE_TS, t0.LAST_UPDATE_USER_I, t0.MOBILE_IP_X, t0.ORIGIN_MP_I, 
t0.PREV_CHANNEL_X, t0.TELEPHONE_NUMBER_X, t0.VERSION_X, t1.DEVICE_I, t1.COORDINATE_I, 
t1.CREATION_TS, t1.CREATION_USER_I, t1.GENERATED_TS, t1.GPGGA_X, t1.GPGSA_X, 
t1.GPGSV_X, t1.GPRMC_X, t1.GPVTG_X, t1.LAST_UPDATE_TS, t1.LAST_UPDATE_USER_I, 
t1.WORK_ORDER_NUMBER_I 

FROM DEVICE t0, GPS_COORD t1 

WHERE  t0.DEVICE_I = t1.DEVICE_I AND  
t1.GENERATED_TS IN ( select max(GENERATED_TS)
       from GPS_COORD
      group by DEVICE_I )
ORDER BY t1.DEVICE_I ASC, t1.GENERATED_TS DESC

下面的java代码几乎就在那里并生成以下查询,该查询缺少GpsCoord所需的连接字段。如果完成提取,则包含这些字段,但稍后在子查询的where子句中需要连接:

    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

    CriteriaQuery<Device> cq = criteriaBuilder.createQuery(Device.class);

    Root<Device> device = cq.from(Device.class);
    cq.distinct(true);

    Join<Device, GpsCoord> j = device.join(Device_.gpsCoords, JoinType.LEFT);
    //Fetch<Device,GpsCoord> f = device.fetch(Device_.gpsCoords);

    CriteriaQuery<Device> select = cq.select(device);


    Subquery<Timestamp> sq = cq.subquery(Timestamp.class);
    Root<GpsCoord> gpsCoord = sq.from(GpsCoord.class);

    sq.select(criteriaBuilder.greatest(gpsCoord.get(GpsCoord_.generatedTs)));
    sq.groupBy(gpsCoord.get(GpsCoord_.device).get(Device_.deviceI));
    select.where(j.get(GpsCoord_.generatedTs).in(sq));


    TypedQuery<Device> query = this.getEntityManager().createQuery(cq);

生成的查询缺少来自Join oepration的GpsCoord文件

SELECT DISTINCT t0.DEVICE_I, t0.ACTIVE_S, t0.APP_CONFIG_I, t0.PREV_APP_CONFIG_I,     
t0.APP_CONFIG_CONFIRMED_S, t0.APP_CONFIG_RECEIPT_D, t0.APP_CONFIG_SENT_S, 
t0.CHANNEL_X,     t0.CREATION_TS, t0.CREATION_USER_I, t0.DEST_QUEUE_C, t0.DIVISION_C, 
t0.LAN_IP_X, t0.LAST_UPDATE_TS, t0.LAST_UPDATE_USER_I, t0.MOBILE_IP_X, t0.ORIGIN_MP_I, 
t0.PREV_CHANNEL_X, t0.TELEPHONE_NUMBER_X, t0.VERSION_X 

FROM SPW_OWN.DEVICE t0, SPW_OWN.GPS_COORD t1 

WHERE (t1.GENERATED_TS IN (SELECT MAX(t2.GENERATED_TS) FROM SPW_OWN.GPS_COORD t2, 
SPW_OWN.DEVICE t3 WHERE t2.DEVICE_I = t3.DEVICE_I GROUP BY t3.DEVICE_I)) 

AND t0.DEVICE_I = t1.DEVICE_I(+)

使用CriteriaQuery中的多选项会在执行时生成正确的SQL,但在调用后会抛出以下异常:

引起:java.lang.Exception:java.lang.RuntimeException:找不到带有参数类型“[class java.lang.String ... java.sql.Timestamp]”的“类Device”的构造函数数据。

CriteriaQuery<Device> select = cq.multiselect(
                    //"deviceI",
                    device.get(Device_.deviceI),
                    //"activeS",
                    device.get(Device_.activeS),
                    //"appConfigConfirmedS",
                    device.get(Device_.appConfigConfirmedS),
                    //"appConfigReceiptD",
                    device.get(Device_.appConfigReceiptD),
                    //"appConfigSentS",
                    device.get(Device_.appConfigSentS),
                    //"channelX",
                    device.get(Device_.channelX),
                    //"destQueueC",
                    device.get(Device_.destQueueC),
                    //"lanIpX",
                    device.get(Device_.lanIpX),
                    //"mobileIpX",
                    device.get(Device_.mobileIpX),
                    //"prevChannelX",
                    device.get(Device_.prevChannelX),
                    //"telephoneNumberX",
                    device.get(Device_.telephoneNumberX),
                    //"versionX"
                    device.get(Device_.versionX),
                    //"device",
                    j.get(GpsCoord_.device),
                    //"gpggaX",
                    j.get(GpsCoord_.gpggaX),
                    //"gprmcX",
                    j.get(GpsCoord_.gprmcX),
                    //"gpgsaX",
                    j.get(GpsCoord_.gpgsaX),
                    //"gpgsvX",
                    j.get(GpsCoord_.gpgsvX),
                    //"gpvtgX"
                    j.get(GpsCoord_.gpvtgX),
                    j.get(GpsCoord_.generatedTs)
                    );

1 个答案:

答案 0 :(得分:1)

一些问题,

  • 你打电话,sq.from(GpsCoord.class);两次
  • 使用device.fetch(Device_.gpsCoords);也将获取对象,并将加入它两次
  • 你的IN不正确,

select.where(criteriaBuilder.get(路径)。在(SQ));