#mysql #spring #spring-boot #hibernate
#mysql #весна #весенняя загрузка #спящий режим
Вопрос:
Я разрабатываю проект spring boot, связанный с базой данных MySQL через Hibernate. Все работает нормально, когда база данных запускается пустой. Однако, когда фиктивный файл data.sql запускается перед запуском приложения, а затем вставкой объектов через приложение, вставка не учитывает предыдущие идентификаторы, что приводит к дублированию записей до тех пор, пока не будет достигнуто количество строк :
Я попытаюсь лучше объяснить на примере :
- При запуске приложения файл data.sql вставляет 3 фиктивных пользователя.
- Достигнув страницы регистрации, чтобы добавить нового пользователя и отправить, Hibernate возвращает ошибку «Дубликат записи»1″ для ПЕРВИЧНОГО ключа», затем «Дубликат записи»2″ для ПЕРВИЧНОГО ключа» и «Дубликат записи» 3 » для ПЕРВИЧНОГО ключа» после повторной попытки два раза.
- При четвертой попытке добавляется пользователь.
Поэтому идентификатор автоматически увеличивается, но не учитывает ранее вставленные строки через data.sql.
Обратите внимание, что я безуспешно пытался поиграть с типом генерации (AUTO / IDENTITY) пользовательского класса, и мой источник данных hibernate находится в режиме создания-удаления.
Обновление: пользовательская сущность :
@Data
@Builder
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "users")
public class User {
public final static Role DEFAULT_ROLE = new Role();
static {
DEFAULT_ROLE.setId(2);
DEFAULT_ROLE.setRole("NORMAL");
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
private int id;
@Column(name = "user_name")
@Length(min = 5, message = "*Your user name must have at least 5 characters")
@NotEmpty(message = "*Please provide a user name")
private String userName;
@Column(name = "email")
@Email(message = "*Please provide a valid Email")
@NotEmpty(message = "*Please provide an email")
private String email;
@Column(name = "password")
@Length(min = 5, message = "*Your password must have at least 5 characters")
@NotEmpty(message = "*Please provide your password")
private String password;
@Column(name = "name")
@NotEmpty(message = "*Please provide your name")
private String name;
@Column(name = "last_name")
@NotEmpty(message = "*Please provide your last name")
private String lastName;
@Column(name = "active")
private Boolean active;
@ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
@Column(name = "phone_number")
@NotEmpty(message = "*Please provide a phone number")
private String phoneNumber;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id", referencedColumnName = "address_id")
private Address address;
}
Есть идеи, что могло бы ее решить? 🙂
Приветствия.
Комментарии:
1. Можете ли вы опубликовать свою пользовательскую сущность? Возможно, там какая-то опечатка…
2. Только что добавлено, спасибо!
Ответ №1:
Проблема не в гибернации, а в операторах в data.sql
.
В этих INSERT
утверждениях вы, вероятно, указываете явные значения для user_id
столбца, следовательно, MySQL не увеличивает свой AUTO_INCREMENT
счетчик. Стратегия генерации Hibernate по умолчанию для MySQL заключается IDENTITY
в том, что она основана на этой AUTO_INCREMENT
функции.
Самое простое решение — опустить users_id
столбец в INSERT
операторах. Однако вы также можете установить начальное AUTO_INCREMENT
значение для таблицы на большее число:
ALTER TABLE users AUTO_INCREMENT=1001
Редактировать: ваше поле идентификатора объявлено как int id
, поэтому оно никогда не может быть null
. Измените его на Integer
, чтобы Hibernate мог различать сохраняемые ( id != null
) и не сохраняемые объекты.
Комментарии:
1. Это помогло мне, поскольку оно действительно установило свойство автоматического увеличения в представление базы данных IntelliJ — теперь я уверен, что оно работает. Однако он по-прежнему возвращает ту же ошибку. Я также заметил кое-что странное: при установке AUTO_INCREMENT=1001 он хорошо увеличивается для следующих инструкций INSERT (1002-1003), однако ошибка по-прежнему возвращает «Дублирующую запись»1″ для первичного ключа», где я ожидал бы «Дублирующую запись»1001» для первичного ключа»… Есть идеи, как это установить?
2. Ваше
id
поле имеет примитивный типint
, поэтому оно инициализируется0
. Измените его на тип в штучнойInteger
упаковке, и все должно работать.