【问题标题】:OpenJPA distinct onOpenJPA 与众不同
【发布时间】:2014-06-23 08:39:41
【问题描述】:

在我的数据库架构中,我与几封电子邮件进行了对话。我想从对话列表中获取最新的电子邮件。在 PostgreSql 中查询:

select distinct on (conversation_id) * 
from email 
where conversation_id in (7085214, 7084964) 
order by conversation_id, processing_date desc

OpenJPA:

(List<Email>) entityManager.createQuery("SELECT
   distinct(email.conversation.id), email FROM Email email WHERE
      email.conversation.id in :id ORDER BY email.conversation.id,
      email.processingDate DESC").setParameter("id", conversationIds);

它会返回对话 ID 的地图和对话中的整个电子邮件列表。

我怎样才能使它正确?

谢谢

【问题讨论】:

  • 没有其他解决办法吗? email对象的映射很长
  • (标准)distinct 运算符不是函数。写distinct(foo),bardistinct foo,bar 相同。所有数据库混淆层(又名“ORM”)仅使用最基本的可用 SQL 功能。使用 DBMS 特定功能的唯一方法是原生 SQL
  • 感谢您的信息

标签: java postgresql openjpa


【解决方案1】:

使用原生 SQL。

唯一的另一种方法是为 OpenJPA 开发一个补丁,“教”它如何在其 JPQL 解析器和查询生成器中使用 PostgreSQL 扩展 DISTINCT ON。大多数 ORM 通过方言挂钩接受此类扩展。不过,不要期望这是一项简单的任务 - 除非您要编写 很多 此类查询,否则原生 SQL 几乎肯定会容易得多。

您不能只使用 DISTINCTDISTINCT ON 之类的函数。他们不是;它们是完全独立的语法。 JPQL 引擎会尝试将其转换为在运行时失败的真正函数调用 - 或者在 distinct on 的情况下,一开始就无法解析它。

顺便说一句,DISTINCT ON 有点像 MySQL 等其他供应商数据库中的GROUP BY,您可以在SELECT 中指定不出现在GROUP BY 或聚合中的列。因此,在 MySQL 中,人们可能只是通过生成一个 MySQL 接受的技术上无效的查询来做到这一点——OpenJPA JPQL 处理程序很可能不会注意到这个问题,所以它会很好地通过它。这个技巧不适用于DISTINCT ON,而且PostgreSQL 严格遵守GROUP BY 的标准,它不会让您使用GROUP BY 生成非确定性查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-15
    • 2015-09-08
    • 2012-07-02
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    相关资源
    最近更新 更多