views:

6645

answers:

5

In Hibernate 3, is there a way to do the equivalent of the following MySql limit in HQL.

select * from a_table order by a_table_column desc limit 0, 20;

I don't want to use setMaxResults if possible. This definitely was possible in the older version of Hibernate/HQL, but seems to have disappeared.

+3  A: 

If you don't want to use setMaxResults() on the Query object then you could always revert back to using normal SQL.

pjp
That's not really all that exciting.
stevedbrown
I don't find HQL exciting either. Why not write a view on your DB server that applies the limit and then get HQL to look at that view :P
pjp
It's just one of those things, while SQL is much easier than HQL for each query, creating views and writing native SQL tends to be not so great for refactoring. I try to avoid it when I can. That actual real problem was the I wrote my MySQL query wrong anyways and thought setMaxResults was being weird. It wasn't.
stevedbrown
+10  A: 

In typically patronising fashion, Gavin King posted this on the Hibernate forum a few years back when asked about why this worked in Hibernate 2 but not in Hibernate 3:

Limit was never a supported clause in HQL. You are meant to use setMaxResults().

So if it worked in Hibernate 2, it seems that was by coincidence, rather than by design. I think this was because the Hibernate 2 HQL parser would replace the bits of the query that it recognised as HQL, and leave the rest as it was, so you could sneak in some native SQL. Hibernate 3, however, has a proper AST HQL Parser, and it's a lot less forgiving.

I think Query.setMaxResults() really is your only option.

skaffman
I was hoping somehow that they realized that that is annoying. Also, if you looked at the source code, they had implemented it for every database, and every database is different. Oh well, that's sad.
stevedbrown
I would argue that Hibernate 3's approach is more correct. Your usage of Hibernate is meant to be database-agnostic, so you should have to do these sorts of things in an abstract manner.
matt b
I agree, but it makes migration is royal pain in the ass when features are dropped like that.
skaffman
+1  A: 

If you don't want to use setMaxResults, you can also use Query.scroll instead of list, and fetch the rows you desire. Useful for paging for instance.

Lluis Martinez
+3  A: 

What about when you want to use a subquery select inside of your main select statement. It needs to return only 1 item.

Mandrake
A: 

My observation is that even you have limit in the HQL (hibernate 3.x), it will be either causing parsing error or just ignored. (if you have order by + desc/asc before limit, it will be ignored, if you don't have desc/asc before limit, it will cause parsing error)

Xingsheng