解决Hibernate不支持PostgreSQL中双冒号(::)的Bug
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了解决Hibernate不支持PostgreSQL中双冒号(::)的Bug,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2713字,纯文字阅读大概需要4分钟。
内容图文
![解决Hibernate不支持PostgreSQL中双冒号(::)的Bug](/upload/InfoBanner/zyjiaocheng/1291/fa31f724371a4ae68938821542a512f1.jpg)
在PostgreSQL中,双冒号(::)的作用是类型转换,而在Hibernate中,SQL中冒号的作用是命名参数,用于SQL中命名参数的匹配,这时,当在PostgreSQL数据库环境中,正常的SQL本身包括双冒号时,通过Hibernate进行查询就会报错,这个应该是Hibernate的一个Bug,怎么解决呢,本文将给出方案。
通过研究Hibernate的源代码,发现了问题所在,问题出在org.hibernate.engine.query.spi.ParameterParser,这个类构造方法为私有,包括若干个静态方法,无法通过扩展二次开发的方式解决,遇到这个问题的,只能自行修改Hibernate的源代码,然后编译。
经过分析,只需要修改其中的parse方法即可,下面的代码即为修改后的代码,测试了一下,大体应该是没问题的,该问题的发现、开发、测试是在Hibernate4.2.15版本下进行的,其他版本如有问题,请开发者自行处理。
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; //增加了双冒号的处理 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( indx + 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 ); } } } }
原文:http://my.oschina.net/liyuj/blog/382986
内容总结
以上是互联网集市为您收集整理的解决Hibernate不支持PostgreSQL中双冒号(::)的Bug全部内容,希望文章能够帮你解决解决Hibernate不支持PostgreSQL中双冒号(::)的Bug所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。