In PostgreSQL, a double colon (::) is a type conversion, whereas in Hibernate, the colon in SQL is named parameters for matching named parameters in sql, when the normal SQL itself includes double colons in the PostgreSQL database environment. Hibernate through the query will be error, this should be hibernate a bug, how to solve it, this article will give a plan.
By studying Hibernate's source code, we discovered the problem, The problem is org.hibernate.engine.query.spi.ParameterParser, this class construction method is private, including a number of static methods, can not be solved by extending two times development, encountered this problem, can only modify Hibernate's source code, and then compile.
After analysis, only need to modify the parse method, the following code is the modified code, testing, the general should be no problem, the problem of discovery, development, testing is carried out in the Hibernate4.2.15 version, the other version if there is a problem, please the developer to deal with their own.
Public static void parse (String sqlstring, recognizer recognizer) throws queryexception { boolean hasmainoutputparameter = startswithescapecalltemplate ( sqlString ); boolean foundmainoutputparam = false; int stringlength = sqlstring.length (); boolean inQuote = false; for ( int indx = 0; indx < stringLength; indx++ ) { char c = sqlstring.charat ( indx ); if ( inQuote ) { if ( ' == c ) { inQuote = false; } recognizer.other ( c ); } else if ( ' \ ') == c ) { inQuote = true; recognizer.other ( c ); } else if ( ' \ \ ' == c ) { // skip sending the backslash and instead send then next character, treating is as a literal recognizer.other ( sqlString.charAt ( ++ indx ) ); } else { if ( c == ': ' ) { // named parameter int right = stringhelper.firstindexofchar ( sqlString, parserhelper.hql_separators_bitset, indx + 1 ); int choplocation = right < 0 ? sqlstring.length () : right; //added double colon handling if (Sqlstring.charat ( indx+1 ) != ': ') { String param = sqlstring.SUBSTRING ( indx + 1, chopLocation ); if ( stringhelper.isempty ( param ) ) { throw new queryexception ( "Space is not allowed after parameter prefix ': ' [' + sqlString + '] ' ); } recognizer.namedparameter ( param, indx ); indx = chopLocation - 1; }else{ recognizer.other (c); recognizer.other (c); indx++; } } else if ( c == '? ') ) { // could be either an ordinal or jpa-positional parameter if ( indx < stringLength - 1 && character.isdigit ( sqlstring.charat ( indx + 1 ) ) ) { // a peek ahead showed this as an JPA-positional parameter int right = Stringhelper.firstindexofchar ( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 ); int chopLocation = right < 0 ? Sqlstring.length () : right; String param = Sqlstring.substring (&NBSP;INDX&NBsp;+ 1, choplocation ); // make sure this "Name" is an integral try { integer.valueof ( param ); } catch ( NumberFormatException e ) { throw new queryexception ( "Jpa-style positional param was not an integral ordinal " ); } recognizer.jpapositionalparameter ( param, indx ); indx = chopLocation - 1; } else { if ( hasMainOutputParameter && !foundMainOutputParam ) { foundMainOutputParam = true; recognizer.outparameter ( indx ); } else { recognizer.ordinalparameter ( indx ); } } } else { recognizer.other ( c ); } } } }
Resolves hibernate does not support double colons in PostgreSQL (::) bugs