Почему выбрасывает JdbcSQLException

329
01 сентября 2017, 21:34

Пытаюсь реализовать метод add для добавления записи в БД.

PreparedStatement preparedStatement = null;
String sql = "INSERT INTO EMPLOYEE (ID, FIRST_NAME, LAST_NAME, BIRTHDAY, ADDRESS_ID) VALUES (?, ?, ?, ?, ?)";
try {
    preparedStatement = connection.prepareStatement(sql);
    preparedStatement.setLong(1, employee.getId());
    preparedStatement.setString(2, employee.getFirstName());
    preparedStatement.setString(3, employee.getLastName());
    preparedStatement.setDate(4, employee.getBirthDay());
    preparedStatement.setLong(5, employee.getAddressId());
    preparedStatement.executeUpdate();
} catch (SQLException e) {
    e.printStackTrace();
}

настойчиво в строке preparedStatement.executeUpdate() бросает исключение:

org.h2.jdbc.JdbcSQLException: Нарушение уникального индекса или первичного ключа: "PRIMARY KEY ON PUBLIC.EMPLOYEE(ID)"
    Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.EMPLOYEE(ID)"; SQL statement:
    INSERT INTO EMPLOYEE (ID, FIRST_NAME, LAST_NAME, BIRTHDAY, ADDRESS_ID) VALUES (?, ?, ?, ?, ?) [23505-196]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
        at org.h2.message.DbException.get(DbException.java:179)
        at org.h2.message.DbException.get(DbException.java:155)
        at org.h2.mvstore.db.MVPrimaryIndex.add(MVPrimaryIndex.java:139)
        at org.h2.mvstore.db.MVTable.addRow(MVTable.java:705)
        at org.h2.command.dml.Insert.insertRows(Insert.java:156)
        at org.h2.command.dml.Insert.update(Insert.java:114)
        at org.h2.command.CommandContainer.update(CommandContainer.java:101)
        at org.h2.command.Command.executeUpdate(Command.java:260)
        at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:164)
        at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:150)
        at service.EmployeeService.add(EmployeeService.java:31)
        at Domain.main(Domain.java:49)

Я так понимаю, ему не нравится, что я даю ему запись с полем ID, которое должно быть уникальным. А в данном методе оно к нему приходит без всяких проверок - as is.

Как избежать вываливания данной ошибки? Или просто игнорировать? Ибо

Process finished with exit code 0

Или я не прав и машине что-то другое не нравится?

Answer 1

Я так понимаю, ему не нравится, что я даю ему запись с полем ID, которое должно быть уникальным.

Верно.
Возможны 2 подхода - либо вы в приложении будете самостоятельно гарантировать уникальность id при вставке новых записей, либо, более простой вариант - за вас это будет делать БД (генерировать новый id при каждой вставке в таблице).
В h2, насколько я помню, есть тип данных serial, который имеет встроенный sequence и при вставке очередной записи будет сгенерирован id на 1 больше предыдущего. В БД, не имеющих похожего типа данных, sequence создается вручную и значения берутся из него (либо в приложении перед вставкой, либо в триггере, повешенном на операцию вставки в таблицу).

Как избежать вываливания данной ошибки? Или просто игнорировать? Ибо

 Process finished with exit code 0

Процесс завершился "успешно" т.к. вы отловили исключение (хотя и никак не отработали).

Answer 2

Вообще с трудом улавливаю из-за чего весь сыр-бор. Надо просто посмотреть DDL скрипт создания таблицы EMPLOYEE, если там написано что-то типа:

 CREATE TABLE EMPLOYEE ( 
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    # blah-blah
 )

Тогда не надо выёживаться и не вставлять самому поле ID, а если не AUTOINCREMENT, то тогда надо самому озаботиться уникальностью ключа ID

В 99% случаях используется автоинкремент.

Answer 3

Вам необходимо либо изменить в таблице первичный ключ, либо вставлять записи с с идентификаторами, которых в базе еще нет. Поскольку ID обычно задается не пользователем а системой, вам необходимо изменить логику создания класса Employee.

READ ALSO
Растянуть элемент на всю высоту

Растянуть элемент на всю высоту

Как растянуть элемент на всю высоту не используя height:100%?

453
Смена цвета строки DataGrid

Смена цвета строки DataGrid

Как программно можно менять цвет строки в DataGrid? Например, приходит новое сообщение и нужная строка выделяется определенным цветом

340
Синдром ломающегося базового класса [требует правки]

Синдром ломающегося базового класса [требует правки]

Объясните "Синдром ломающегося базового класса"Интересуют конкретные примеры

435