Skip to content

Instantly share code, notes, and snippets.

@Baztoune
Last active December 12, 2015 05:28
Show Gist options
  • Save Baztoune/4722048 to your computer and use it in GitHub Desktop.
Save Baztoune/4722048 to your computer and use it in GitHub Desktop.
I work with Hibernate 3.2.6.ga. I store my enum values as String in my database, using @Enumerated(EnumType.STRING). This time, I had to work with "native" SQL for some reason, so I used SQLQuery, and tried to filter my request by setting an enum value, but the query returned 0 result instead of, let's say 15.

It appeared that the final String parameter set in the SQL query was not the one I expected. Logging the SQL parameters (org.hibernate.type=TRACE) shows that the parameter looks like some hash (2c6d8085fef280...), not a regular String. While debugging the SQLQuery, i saw that the namedparameter's type was of type SerializableType instead of StringType. Hence Hibernate calls NullableType.nullSafeSet() in his Loader.bindNamedParameters() method, that calls Serializable.set(), which sets the Enum value as bytes. So the problem seems to come from TypeFactory.heuristicType() that doesn't find any suitable type for my Enum, except SerialisableType.

I didn't find any corresponding JIRA on hibernate bugtracker or anything else on Google, except that https://forum.hibernate.org/viewtopic.php?f=9&t=984527 so I don't really know if it's worth reporting the bug (maybe that branch is not even maintained anymore?)

TL;DR

don't set enum parameters in SQLQuery!

// don't do
sqlQuery.setParameter("myStatus", MyStatusEnum.OK); // NOP!
// instead, do
sqlQuery.setParameter("myStatus", MyStatusEnum.OK.name()); // YEP!
// or even, to be sure
sqlQuery.setString("myStatus", MyStatusEnum.OK.name()); // YEP!
/*
* Doesn't work
*/
StringBuilder sqlStringBad = new StringBuilder()
.append("SELECT id,status")
.append(" FROM my_table mt")
.append(" WHERE mt.status in (:myStatusIsAnEnum)");
SQLQuery sqlQBad = delegate.createSQLQuery(sqlStringBad.toString());
Status[] statusListEnum = { Status.OK, Status.NOTYET };
sqlQBad.setParameterList("myStatusIsAnEnum", statusListString);
List<Object[]> resultsBad = sqlQBad.list(); // 0 results
/*
* Works perfectly fine
*/
StringBuilder sqlStringGood = new StringBuilder()
.append("SELECT id,status")
.append(" FROM my_table mt")
.append(" WHERE mt.status in (:myStatusIsAnEnum)");
SQLQuery sqlQGood = delegate.createSQLQuery(sqlStringGood.toString());
String[] statusListString = { Status.OK.name(), Status.NOTYET.name() };
sqlQGood.setParameterList("myStatusIsAnEnum", statusListString);
List<Object[]> resultsGood = sqlQGood.list(); // 15 results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment