【问题标题】:Hibernate/PostgreSQL JPAQueryException when trying to use GROUP BY尝试使用 GROUP BY 时出现 Hibernate/PostgreSQL JPAQueryException
【发布时间】:2012-10-04 14:16:41
【问题描述】:

我在使用 Hibernate 时遇到以下异常:

JPAQueryException 发生:执行查询时出错 select f from Flyer as f join f.events as e where e.start > ?和 e.start 1 组按 f 顺序按 sqrt((-118.39419-f.venue.lng) * (-118.39419-f.venue.lng)+(34.024353-f.venue.lat)*(34.024353-f.场地.lat)) asc:错误:列“venue2_.lng”必须出现在 GROUP BY 子句中或用于聚合函数中

上面显示了查询的 HQL。 HQL生成的SQL如下:

选择 flyer0_.id 作为 id345_,flyer0_.venue_id 作为venue77_345_ 从 flyer0_.id=events1_.flyer_id 上的 flyer0_ 内部加入事件 events1_ 交叉加入场地场地 2_ where flyer0_.venue_id=venue2_.id 和 events1_.start>?和 events1_.start1 组按 flyer0_.id 顺序按 sqrt((-118.39419-venue2_.lng)*(-118.39419-venue2_.lng)+(34.024353-venue2_.lat)*(34.024353-venue2_.lat)) asc 限制?

表格是传单、活动和场地。

事件表跟踪传单的开始和停止时间......一个传单可以在多天重复......因此有多个事件。

每个传单都有一个场地,传单上的广告将在此举行。

就我的数据库而言,我正在使用 Heroku PostgreSQL Crane,如以下 URL 中所述。我相信它使用 PostgreSQL 9.1:

在休眠方面,我正在使用的 Play Framework 1.2.5 似乎使用:

- org.hibernate -> hibernate-core 3.6.10.Final
- org.hibernate -> hibernate-commons-annotations 3.2.0.Final
- org.hibernate -> hibernate-entitymanager 3.6.10.Final
- org.hibernate -> hibernate-validator 4.1.0.Final

我的问题是导致 JPAQueryException 的原因,我该如何解决?

谢谢!

【问题讨论】:

  • 这应该在 PostgreSQL 9.2 中工作,因为 GROUP BY 子句包括主键的处理方式发生了变化。在以前的版本中,也许您也可以在 GROUP BY 中列出 SELECT 列表中的所有列,或者说服 Hibernate?什么Pg版本?休眠版本?
  • 我正在使用 Heroku Postgres Crane。我猜这里 (devcenter.heroku.com/articles/heroku-postgresql) 说他们使用的是 PostgreSQL 9.1。
  • 在 Hibernate 方面,我使用的是 Play Framework 1.2.5,它使用以下内容:hibernate-core 3.6.10.Final, hibernate-commons-annotations 3.2.0.Final, hibernate- entitymanager 3.6.10.Final, hibernate-validator 4.1.0.Final

标签: hibernate postgresql heroku playframework hql


【解决方案1】:

我认为问题在于,在 Pg 9.1 及以下版本中,您必须列出 ORDER BY 中出现在 SELECT 中的所有列,除非它们在聚合中使用。 9.2及以上可以算出,如果PRIMARY KEY列在GROUP BY中,那么其他所有内容也都被隐式分组了。

您似乎可以通过合并子查询来重新表述查询以解决该问题:

select f
from Flyer as f
where exists (
  SELECT 1 FROM f.events as e
  where e.start > ? and e.start < ? and f.popularityTag > 1
)
order by sqrt((-118.39419-f.venue.lng) * (-118.39419-f.venue.lng)+(34.024353-f.venue.lat)*(34.024353-f.venue.lat)) asc

我还没有测试过,而且我写的 HQL 也不多,所以你可能需要对其进行调整,但这个想法应该会得到贯彻。

【讨论】:

  • 使用您提供的休眠模式,查询似乎运行没有错误。我现在注意到,虽然执行我提供的原始查询似乎需要更长的时间,但可以说如果我删除了其中的组。您认为现在查询慢得多还是不应该影响速度?
  • @HelpMeStackOverflowMyOnlyHope 它不应该对性能产生太大影响,它只是 Hibernate 查询生成的一种解决方法。我希望得到大致相同的查询计划。但是:您如何比较未运行的查询的执行时间?我不明白你的评论。
  • @HelpMeStackOverflowMyOnlyHope 通常,您应该使用EXPLAIN ANALYZE(来自 PgAdmin-III 或psql)运行 Hibernate 生成的原始 SQL 并比较查询计划/性能。或者,使用auto_explain (postgresql.org/docs/current/static/auto-explain.html) 从 Hibernate 查询中捕获计划并从 PostgreSQL 日志文件中获取它们。 explain.depesz.com 可用于分析计划并发布指向计划的链接。
  • 很抱歉我之前的评论不够清晰。我想说如果我在没有“group by f”部分的情况下运行我的原始查询,它似乎运行得更快。因此,如果查询是: select f from Flyer as f join f.events as e where e.start > ?和 e.start 1 order by sqrt((-118.39419-f.venue.lng) * (-118.39419-f.venue.lng)+(34.024353-f.venue.lat)*(34.024353-f.venue.lat )) asc
  • @HelpMeStackOverflowMyOnlyHope 好吧,当然,但这是一个不同的查询。也许您可以尝试“SELECT DISTINCT f”而不是使用GROUP BY
猜你喜欢
  • 2020-02-08
  • 2020-03-19
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多