MySQL Ошибка при использовании Statement.RETURN_GENERATED_KEYS - PullRequest
0 голосов
/ 14 января 2020

Я унаследовал старый веб-сайт Servlet / JSP, который был обновлен до Java 1.8.0_201 и MySQL 5.7.28. Недавно я начал получать эту ошибку при добавлении новых записей в базу данных:

Generated keys not requested. You need to specify Statement.RETURN_GENERATED_KEYS to Statement.executeUpdate(), Statement.executeLargeUpdate() or Connection.prepareStatement().

Я гуглил происходящее и обнаружил, что мне нужно добавить Statement.RETURN_GENERATED_KEYS в мой Statement.executeUpdateQuery, поэтому я сделал. Тем не менее, я все еще получаю ошибку. Обновленный код и ошибка появляются в операторе result = stmt.getGeneratedKeys();:

            stmt = con.createStatement();
            switch(queryType) {
                case INSERT_QUERY:
                    stmt.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
                    int autoIncKey = -1;
                    result = stmt.getGeneratedKeys();
                    if (result.next()) {
                        autoIncKey = result.getInt(1);
                    }
                    rows = stmt.getUpdateCount();
                    svr.setGeneratedKey(autoIncKey);
                    obj.setGeneratedKey(autoIncKey);
                    svr.setRows(rows); //Insert/Update/Delete
                    if (rows > 0)
                        svr.setSuccess(true);
                    else
                        svr.setSuccess(false);
                    break;

Однако вставка работает и данные помещаются в базу данных.

Тогда я подумал, что мне следует обновить библиотеку Mysql Connector, поэтому я обновился с версии 5.4 до mysql -connector- java -8.0.18.jar. Все еще получаю ту же ошибку.

Я не использую подготовленные операторы, просто строку для текста запроса. Это строка запроса:

INSERT INTO Flights(rocket_name, weight, angle, baseline, egg_id, shockcord_id, notes, date, rocketModelID, mission_specialists, flight_engineers, teacher_id) VALUES ('asdfasdfasd', 98.0, 60.0, 60.0, 2, 2, 'sfdg sfdg sdg sfdg sdfg sfdg sfdg', '2020-01-07', 4,'asdfasdf', 'asdfasdfas', 13);

Определение таблицы для рейсов:

| Flights | CREATE TABLE `Flights` (
  `flight_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `teacher_id` int(11) NOT NULL DEFAULT '0',
  `egg_id` int(10) unsigned NOT NULL DEFAULT '0',
  `shockcord_id` int(10) unsigned NOT NULL DEFAULT '0',
  `rocket_name` varchar(100) NOT NULL DEFAULT '',
  `weight` decimal(10,4) unsigned NOT NULL DEFAULT '0.0000',
  `angle` decimal(10,5) NOT NULL DEFAULT '0.00000',
  `baseline` decimal(10,5) NOT NULL DEFAULT '0.00000',
  `date` date NOT NULL DEFAULT '0000-00-00',
  `rocketModelID` int(11) unsigned NOT NULL DEFAULT '0',
  `flight_engineers` varchar(100) NOT NULL DEFAULT '',
  `mission_specialists` varchar(100) NOT NULL DEFAULT '',
  `notes` text,
  PRIMARY KEY (`flight_id`),
  FULLTEXT KEY `search1` (`mission_specialists`),
  FULLTEXT KEY `search2` (`flight_engineers`),
  FULLTEXT KEY `search3` (`flight_engineers`,`mission_specialists`)
) ENGINE=MyISAM AUTO_INCREMENT=562 DEFAULT CHARSET=latin1 

Я не уверен, как поступить. Любые предложения будут с благодарностью!

Марк

1 Ответ

1 голос
/ 14 января 2020

Рекомендовать изменить код следующим образом:

  • Назовите ключевой столбец

  • Получить количество строк из executeUpdate вызова

  • Не вызывать getGeneratedKeys(), если не было вставлено ни одной строки

rows = stmt.executeUpdate(query, new String[] { "flight_id" });
int autoIncKey = -1;
if (rows > 0) {
    result = stmt.getGeneratedKeys();
    if (result.next()) {
        autoIncKey = result.getInt(1);
    }
}
svr.setGeneratedKey(autoIncKey);
obj.setGeneratedKey(autoIncKey);
svr.setRows(rows); //Insert/Update/Delete
svr.setSuccess(rows > 0);

Хотя, действительно, один оператор INSERT использует VALUES всегда будет вставлять ровно одну строку, поэтому проверка количества строк совершенно не нужна. Если бы строка не была вставлена, возникло бы исключение, поэтому ваш код можно уменьшить до:

stmt.executeUpdate(query, new String[] { "flight_id" });
try (ResultSet result = stmt.getGeneratedKeys()) {
    result.next();
    int autoIncKey = result.getInt(1);
    svr.setGeneratedKey(autoIncKey);
    obj.setGeneratedKey(autoIncKey);
}
svr.setRows(1);
svr.setSuccess(true);
...