Springboot 2 CrudRepository.save всегда выдает исключение ConstraintViolationException - PullRequest
0 голосов
/ 12 ноября 2018

Я перенес версию Springboot с 1.4.3.RELEASE на 2.1.0.RELEASE в моем проекте. После этого CrudRepository.save () всегда выдает org.hibernate.exception.ConstraintViolationException: не удалось выполнить инструкцию.

Вот что я вижу в журналах:

o.h.e.j.s.SqlExceptionHelper[m: SQL Error: 1062, SQLState: 23000
o.h.e.j.s.SqlExceptionHelper[m: Duplicate entry '11' for key 'PRIMARY'
o.h.i.ExceptionMapperStandardImpl[m: HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement

Это сущность, которую я пытаюсь спасти.

@Getter
@Setter
@Entity
@Table(name = "project_m")
public class Project {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "name" , nullable = false)
    private String name;

    //other fields

}

Ответы [ 3 ]

0 голосов
/ 14 ноября 2018

Я нашел решение этой проблемы, установив большое значение в таблице hibernate_sequence.Я видел, что значение первичного ключа из-за повторяющейся ошибки первичного ключа генерируется из таблицы с именем hibernate_sequence.

Когда мы устанавливаем GenerationType.AUTO в сущности, Hibernate выбирает стратегию генерации на основе диалекта Hibernate.В более старых версиях Hibernate выбирал GenerationType.IDENTITY по умолчанию для баз данных MySQL.

Теперь он выбирает GenerationType.TABLE, который использует таблицу базы данных для генерации первичных ключей

0 голосов
/ 14 ноября 2018

ConstraintViolationException произошло из-за того, что ограничение вашего первичного ключа для базы данных SQL нарушает В SQL первичный ключ является уникальным ключом для идентификации записи, база данных будет выдавать исключение при попытке вставить дублирующее значение в первичный столбец. который, в свою очередь, перешел в спящий режим и передается в ваш код и является причиной этого исключения.

С Springboot 1.4.3.RELEASE до 2.1.0.RELEASE Обновлена ​​версия Hibernate с 5.0 до 5.3.

Способ, которым Hibernate интерпретирует тип генерации AUTO, изменился, начиная с версии Hibernate 5.0

Если вы используете strategy="AUTO", Hibernate сгенерирует таблицу с именем hibernate_sequence, чтобы указать следующий номер для последовательности идентификаторов. Возможно, вы забыли добавить функцию автоинкремента к ПК вашего стола.

Еще один способ исправить это использовать следующие аннотации с strategy="AUTO"

@Id
@GeneratedValue(
    strategy= GenerationType.AUTO, 
    generator="native"
)
@GenericGenerator(
    name = "native", 
    strategy = "native"
)
private Long id;

Вы можете использовать стратегию генерации strategy="IDENTITY", чтобы принудительно использовать функцию автоинкремента, доступную в SQL, и избежать создания таблицы.

Пожалуйста, проверьте здесь , чтобы получить более подробную информацию

0 голосов
/ 13 ноября 2018

Что изменилось с Springboot 1.4.3.RELEASE на 2.1.0.RELEASE - это внутренняя версия Hibernate с 5.0 до 5.3 .

И что изменилось в этом, так это то, как работает SequenceGenerator, который используется, если стратегией является GenerationType.AUTO (как в вашем случае).enter image description here

Ссылка на документ о миграции hibernate здесь .

Подробнее о стратегии генерации hibernate здесь .

Я предполагаю, что в эту таблицу вставлено 2 параллельных сеанса, и теперь оба они совместно используют локальную копию порядкового номера, которая создает это столкновение.Хотя не уверен!

Я бы предложил изменить стратегию на GenerationType.SEQUENCE и попробовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...