JPQL“DISTINCT”只返回一个结果

时间:2013-07-10 04:15:25

标签: jpa distinct jpql

我对JPQL中的DISTINCT感到困惑。除了其中一个中的“DISTINCT”之外,我有两个相同的JPQL查询:

String getObjectsForFlow =
    "SELECT  " +
    "    se.componentID " +
    "FROM " +
    "    StatisticsEvent se " +
    "WHERE " +
    "    se.serverID IS NOT NULL " +
    "    AND se.flowID = :uuid " +
    "    AND se.componentID IS NOT NULL " +
    "ORDER BY " +
    "    se.timeStamp desc ";

String getObjectsForFlowDistinct =
    "SELECT DISTINCT " +
    "    se.componentID " +
    "FROM " +
    "    StatisticsEvent se " +
    "WHERE " +
    "    se.serverID IS NOT NULL " +
    "    AND se.flowID = :uuid " +
    "    AND se.componentID IS NOT NULL " +
    "ORDER BY " +
    "    se.timeStamp desc ";

我运行一些代码来获取每个查询的结果并将它们转储到stdout,并且我得到许多行,其中有一些副本用于非不同的,但是对于不同的我只得到一行,这是非独特的一部分名单。

NOT DISTINCT
::: 01e2e915-35c1-6cf0-9d0e-14109fdb7235
::: 01e2e915-35c1-6cf0-9d0e-14109fdb7235
::: 01e2e915-35d9-afe0-9d0e-14109fdb7235
::: 01e2e915-35d9-afe0-9d0e-14109fdb7235
::: 01e2e915-35bd-c370-9d0e-14109fdb7235
::: 01e2e915-35bd-c370-9d0e-14109fdb7235
::: 01e2e915-35aa-1460-9d0e-14109fdb7235
::: 01e2e915-35d1-2460-9d0e-14109fdb7235
::: 01e2e915-35e1-7810-9d0e-14109fdb7235
::: 01e2e915-35e1-7810-9d0e-14109fdb7235
::: 01e2e915-35d0-12f0-9d0e-14109fdb7235
::: 01e2e915-35b0-cb20-9d0e-14109fdb7235
::: 01e2e915-35a8-66b0-9d0e-14109fdb7235
::: 01e2e915-35a8-66b0-9d0e-14109fdb7235
::: 01e2e915-35e2-6270-9d0e-14109fdb7235
::: 01e2e915-357f-33d0-9d0e-14109fdb7235
DISTINCT
::: 01e2e915-35e2-6270-9d0e-14109fdb7235

其他参赛作品在哪里?我希望DISTINCT列表包含11个(我认为)条目。

4 个答案:

答案 0 :(得分:0)

在StatisticsEvent实体类上仔细检查equals()方法。当调用equals()时,这些语义上不同的值可能会返回相同的值,从而产生此行为

答案 1 :(得分:0)

问题是“ORDER BY se.timeStamp”子句。为了满足请求,JPQL将ORDER BY字段添加到SELECT DISTINCT子句中。

这就像JPQL和SQL之间相互作用的边界情况。 JPQL语法明确地将DISTINCT修饰符仅应用于se.componentID,但是当转换为SQL时,将插入ORDER BY字段。

我很惊讶必须选择ORDER BY字段。某些数据库可以返回由SELECTion中不存在的字段进行ORDER处理的数据集。 Oracle可以这样做。我的底层数据库是Derby - 这可能是Derby的限制吗?

答案 2 :(得分:0)

除非按列排序在SELECT中,否则Oracle不支持带有顺序的SELECT DISTINCT。不确定是否有任何数据库。如果不需要DISTINCT(因为行是唯一的而不运行),它将在Oracle中工作,但如果需要运行,则会出错。

你会得到,“ORA-01791:不是SELECTed表达式”

如果您使用的是EclipseLink,则此功能由DatabasPlatform方法控制,

shouldSelectDistinctIncludeOrderBy()

如果您的数据库不需要,您可以扩展您的平台以返回false。

但是,我没有看到添加TIMESTAMP会如何改变查询结果?

答案 3 :(得分:0)

两个查询都是不正确的JPQL查询,因为ORDER BY子句引用了不在选择列表中的项目。 JPA 2.0规范包含与此案例匹配的示例:

  

以下两个查询不合法,因为orderby_item是   没有反映在查询的SELECT子句中。

     

SELECT p.product_name   FROM订单o JOIN o.lineItems l JOIN l.product p JOIN o.customer c
  WHERE c.lastname ='Smith'和c.firstname ='John'   订购p.price

     

SELECT p.product_name
  FROM Order o,IN(o.lineItems)l JOIN o.customer c
  WHERE c.lastname ='Smith'和c.firstname ='John'   订购   o.quantity

当然,如果实现可以提供明确的错误消息而不是试图猜测错误查询的预期结果会更好。