как решить org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; - PullRequest
0 голосов
/ 04 марта 2011

Я использую HSQLDB в качестве базы данных.Я хочу получить первичный ключ последней вставленной строки.для этого я должен вернуть запрос в мой класс Java, как показано ниже:

final String query = "INSERT INTO polling_log (start_date,status,action) VALUES(CURRENT_TIMESTAMP,?,?); CALL IDENTITY();";
    GeneratedKeyHolder generatedKeyHolder = new GeneratedKeyHolder();
    int update = adapterJdbcTemplate.update(new PreparedStatementCreator() {
        @Override
        public PreparedStatement createPreparedStatement(
                Connection connection) throws SQLException {

            PreparedStatement preparedStatement = connection
                    .prepareStatement(query);
            preparedStatement.setInt(1, pollingLogVO.getStatus());
            preparedStatement.setString(2, pollingLogVO.getAction());
            System.out.println(preparedStatement.getGeneratedKeys().getFetchSize());
            return preparedStatement;
        }
    }, generatedKeyHolder);

    System.out.println("###################### "+ update);

    Number logId = generatedKeyHolder.getKey();
    pollingLogId = logId.intValue();

, и для хранения запроса я использовал GeneratedKeyHolder.но при выполнении этого я получаю исключение:

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar []; nested exception is java.sql.SQLException: unexpected token: IDENTITY
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:98)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:602)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:817)
    at com.platysgroup.lmex.adapter.moodle.dao.LogDao.insertPollingLog(LogDao.java:36)
    at com.platysgroup.lmex.adapter.MoodlePostingTask.insertPollingLog(MoodlePostingTask.java:134)
    at com.platysgroup.lmex.adapter.MoodlePostingTask.run(MoodlePostingTask.java:55)
    at java.util.TimerThread.mainLoop(Timer.java:512)
    at java.util.TimerThread.run(Timer.java:462)
Caused by: java.sql.SQLException: unexpected token: IDENTITY
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
    at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
    at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:248)
    at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:302)
    at com.platysgroup.lmex.adapter.moodle.dao.LogDao$1.createPreparedStatement(LogDao.java:41)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:580)
    ... 6 more
Caused by: org.hsqldb.HsqlException: unexpected token: IDENTITY
    at org.hsqldb.error.Error.parseError(Unknown Source)
    at org.hsqldb.ParserBase.unexpectedToken(Unknown Source)
    at org.hsqldb.ParserCommand.compileStatement(Unknown Source)
    at org.hsqldb.Session.compileStatement(Unknown Source)
    at org.hsqldb.StatementManager.compile(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    ... 12 more

Ответы [ 3 ]

0 голосов
/ 12 мая 2012

Следующая ссылка содержит то, что вам нужно:

http://www.devdaily.com/blog/post/jdbc/spring-jdbc-insert-auto-generated-key

0 голосов
/ 12 мая 2012

Проблема с этой строкой (обернуто для ясности):

final String query = "INSERT INTO polling_log (start_date,status,action) VALUES(CURRENT_TIMESTAMP,?,?); CALL IDENTITY();";

Проблема в том, что IDENTITY является зарезервированным словом в SQL; у него уже есть предопределенное значение, и поэтому его нельзя использовать в выражении CALL. (Я не знаю, для чего он на самом деле используется; полное определение SQL огромно и содержит очень большое количество зарезервированных слов.) Непосредственный обходной путь заключается в том, чтобы заключить проблемное слово в двойные кавычки (что потребует быть в кавычках из-за нахождения в строке Java):

final String query = "INSERT INTO polling_log (start_date,status,action) VALUES(CURRENT_TIMESTAMP,?,?); CALL \"IDENTITY\"();";

Однако, если вы просто вызываете это, чтобы получить вставленную строку, STOP! Просто позвольте Spring сделать всю работу за вас, при условии, что у вас есть JDBC 3.0 или более поздняя версия (т.е. , Java 5 или более поздняя версия).

0 голосов
/ 05 мая 2011

Насколько я знаю, вы не можете поместить более одной инструкции в одну строку для выполнения. Вместо этого выполните две отдельные операции.

...