0

Querying by HQL with

select a from Article a join a.tags t 
where t.name in (:tags) 
group by a 
having count(t)=:tag_count

using HSQLDB in Grails produces an SqlException "Not in aggregate function...". Looking at the generated SQL provides

SELECT a.id, a.title, a.url, ....
..
GROUP BY a.id
HAVING ..

In some MySQL products this works, I have heard, but apparently not in HSQLDB. I don't understand:

  1. Why does Hibernate generate faulty SQL? Or does it not?
  2. Why is HSQLDB not allowing the grouping on just the id while selecting the lot, I mean its the primary key after all and my SELECT does not introduce indeterministic values such as a random or current time
Tom
  • 1,965
  • 3
  • 25
  • 33

3 Answers3

1

Just found this bug in Hibernate issue tracker. It seems this is a known problem that has been around for five years.... Unbelievable. Its always amazing to see that seemingly fundamental things can be broken for such a long time.

Tom
  • 1,965
  • 3
  • 25
  • 33
0

The generated SQL is not very right, since we should GROUPBY all non-aggregated properties in SELECT clause. For example:

SELECT name,category FROM books
GROUP BY category;

The above query will give false data, because it will only give 1 rows for a category(even if running in MySQL). Instead, it should be done like this:

SELECT name,category FROM books
GROUP BY name,category;

EDIT: After some more investigating, I realize that MySQL is the one who doesn't follow the rule. For some sake of query optimization, MySQL does permit not full GROUP BY query(by default, there's an option to turn this function off). If you run the query on other databases like Oracle or HSQLDB, you will get errors. The detail answer is found in this question.

EDIT2: To re-write the query by your way, there's no other mean except listing all non-aggregation selected properties in Group By clause. From Hibernate doc:

Hibernate also does not currently expand a grouped entity, so you cannot write group by cat if all properties of cat are non-aggregated. You have to list all non-aggregated properties explicitly.

@Tom: But I think that maybe you don't need all the fields in Article table. If that is the case, would you mind provide more information about the domain class and what you are going to query, so we can see the problem clearer?

Community
  • 1
  • 1
Hoàng Long
  • 10,746
  • 20
  • 75
  • 124
  • Okay, cheers, yet I am not too worried about understanding MySQL but rather how I can get Hibernate to work properly in my Grails/HQL application, or if its a DataSource/HSQLDB configuration thing. – Tom Mar 31 '11 at 07:43
  • @Tom: so you want to make Hibernate generate valid SQL query? I don't know if HSQLDB have an option to loose this option, but you can change the query – Hoàng Long Mar 31 '11 at 07:53
  • @Tom: I think there's a work-around for this: you can select a.id first in the groupBy query, then re-query again using those ids. Maybe there's a better way using criteria, but I'm not familiar with your domain. Can you give more details? – Hoàng Long Mar 31 '11 at 07:59
  • Yes that would do the trick. Would you know how to rewrite the HQL in my question above to do work that way? – Tom Mar 31 '11 at 08:16
0

This type of query is actually allowed by the current SQL Standard so long as ID is a primary key column. But this is considered an optional feature of the Standard and not required to be supported by database engines.

HSQLDB 2.x supports this when ID is a primary key column.

fredt
  • 24,044
  • 3
  • 40
  • 61