解決Hibernate不支援PostgreSQL中雙冒號(::)的Bug

來源:互聯網
上載者:User

標籤:

        在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 );                }            }        }    }


解決Hibernate不支援PostgreSQL中雙冒號(::)的Bug

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.