Hibernate Colon (:) Bug
In our main product we’ve built a pretty heavy-weight, powerful block of code for allowing users to build and execute very complex queries through the GUI. The permutations covered by this widget recently uncovered a hibernate bug and want to quickly write up this overview so google can start indexing it
As a short explanation, the queries being generated by the code backing this GUI-based query builder was generating fragments that involved type casts. We are using PostgreSQL and they looked like this:
(some_column > 0)::integer
This has worked great for awhile but last night I uncovered a combination of factors that causes this to break. If you are:
- Using the Criteria API to build up a query
- Using sqlRestrictions in your query
- Using colons in your sql restriction (in my case it was the ::type casting for PostgreSQL)
- Have a filter applied to your queries. In our case it was a filter being set by a
@FilterDefannotation on the model object
If you combine these factors you will get an error along the lines of Invalid filter-parameter name format. When I googled this I ran into the common scenario of only finding hits within public-facing code repositories for the project throwing the error. Hopefully the next searcher finds it here.
Basically I think what happens in this case is colons aren’t properly escaped and hibernate then expects named parameters. In my case it was seeing ::integer and thinking I had a named parameter called :integer and the code in SessionImpl.java of the hibernate project was blowing up because this doesn’t look like a valid parameter name. It would have been much harder to track down the problem if hibernate wasn’t open source.
If I disabled the filter it worked fine. In either case the complete workaround is thanks to PostgreSQL and involves using this alternate casting syntax:
CAST ((some_column > 0) AS integer)
Thank goodness PostgreSQL provides different types of syntax for this. I’ll probably post this to the Hibernate JIRA before too long, i’ll likely somehow be told it isn’t a bug.