Есть ли способ извлечь первичный ключ (или ROWID) с помощью NamedParameterJdbcTemplate и GeneratedKeyHolder?

Я пытаюсь извлечь ROWID или первичный ключ, используя Spring NamedParameterJdbcTemplate и GeneratedKeyHolder.

Я пытаюсь сделать что-то вроде этого.

MapSqlParameterSource parameters = new MapSqlParameterSource()
                .addValue("param1", value1)
                .addValue("param2", value2);
KeyHolder keyHolder = new GeneratedKeyHolder();
namedParameterJdbcTemplate.update("INSERT INTO TABLE(ID, col1, col2)"
                + "VALUES(TABLE.TABLE_SEQ.NEXTVAL, :param1, :param2)",
                parameters, keyHolder);

После выполнения вышеуказанного запроса, когда я пытаюсь выполнить keyHolder.getKey().longValue(), возникает исключение ниже.

HTTP Status 500 - Request processing failed; nested exception is org.springframework.dao.DataRetrievalFailureException: The generated key is not of a supported numeric type. Unable to cast [oracle.sql.ROWID] to [java.lang.Number]

Когда я прошел через этот http://docs.oracle.com/cd/B28359_01/java.111/b31224/datacc.htm Я понимаю (надеюсь, понял), что ojdbc не сопоставляет RowId oracle с RowId java.

Может ли кто-нибудь предложить, есть ли способ извлечь ключ? (Да, это можно сделать с помощью PreparedStatement, но это делает мой код немного уродливым для чтения и обработки при некоторых условиях). Ваши предложения очень ценятся.


person darwinbaisa    schedule 12.07.2012    source источник
comment
Я не знаю, есть ли у вас такая же проблема, но вы проверяете эту ссылку stackoverflow.com/questions/4496336/nextval-jdbc-insert-problem .   -  person Calin Andrei    schedule 12.07.2012
comment
ROWID не является числовым типом, попробуйте получить строку.   -  person Jason    schedule 13.07.2012


Ответы (2)


Вы должны использовать это

namedParameterJdbcTemplate.update("INSERT INTO TABLE(ID, col1, col2)"
            + "VALUES(TABLE.TABLE_SEQ.NEXTVAL, :param1, :param2)",
            parameters, keyHolder, new String[]{"ID"});
person Wins    schedule 13.07.2012
comment
он не работает для таблицы, имеющей более 7 столбцов, у вас есть какое-либо решение этой проблемы? - person Bhargav Modi; 22.01.2015
comment
@BhargavModi Какое исключение? - person Wins; 22.01.2015
comment
Можете ли вы показать структуру своей таблицы и то, как вы используете NamedParameterJdbcTemplate? - person Wins; 23.01.2015
comment
Можете ли вы удалить RETURNING INPUTREQUESTID? - person Wins; 26.01.2015
comment
Вероятно, это всего лишь опечатка, но я заметил, что вы пропустили '(' после VALUES - person Wins; 27.01.2015
comment
запрос вылечен и исправлен, но если я использую 7 столбцов для вставки, он работает нормально, как и ожидалось. но если я сделаю это до 8 столбцов, это даст исключение - person Bhargav Modi; 27.01.2015
comment
Исключение, похоже, исходит от драйвера jdbc. Какую версию драйвера Oracle вы используете? Вы пытались установить более новую версию? - person Wins; 27.01.2015
comment
Драйвер oracle 11 g jdbc, и я обнаружил, что проблема связана с jdbc, но я не смог найти решение для этого или мне не разрешили изменить его на более высокую версию, поэтому я искал решение для программирования. [здесь полезная ссылка, похожая на мою проблему] (stackoverflow.com/q/277744/2749470) - person Bhargav Modi; 27.01.2015

Вот полностью рабочий пример: предполагается, что база данных - это Oracle, а имя столбца, в котором хранится сгенерированный идентификатор, - "GENERATED_ID" (может быть любым именем)

       public Integer insertRecordReturnGeneratedId(final MyObject obj)
        {
        final String INSERT_QUERY = "INSERT INTO MY_TABLE  VALUES(GENERATED_ID_SEQ.NEXTVAL, :param1, :param2)";
        try
            {
                MapSqlParameterSource parameters = new MapSqlParameterSource().addValue( "param1", obj.getField1() ).addValue( "param2",  obj.getField1() ) ;
                final KeyHolder holder = new GeneratedKeyHolder();
                this.namedParameterJdbcTemplate.update( INSERT_QUERY, parameters, holder, new String[] {"GENERATED_ID" } );
                Number generatedId = holder.getKey();
               // Note: USING holder.getKey("GENERATED_ID") IS ok TOO.
                return generatedId.intValue();
            }
            catch( DataAccessException dataAccessException )
            {
    }
    }
person supernova    schedule 06.08.2016