Как настроить таблицы DataBase и JavaCode таким образом что бы данные сначала добавлялись в главную таблицу а потом благодаря FOREIGN KEY в дочернюю
Я пишу REST API приложение на SpringBoot. Использую MySQL. У меня есть сущности User и Role, связанные друг с другом @ManyToMany. У меня есть таблица authorities которую я использую в качестве @JoinTable. Таблица authorities имеет два столбца: username - который является вторичным ключом для связи с таблицей users, и authority который делает то же для таблицы roles. При добавлении нового user в таблицу user я получаю:
Cannot add or update a child row: a foreign key constraint fails
Поискав в интернете я обнаружил, что такая ошибка возникает если я пытаюсь добавить в дочернюю таблицу значение которого нет в главной таблице. С таблицей roles такой проблемы нет, потому что там всего два значения которыми я оперирую: "USER" и "ADMIN". После внимательного изучения контроллера и метода createUser() которым я пользуюсь, я уверен что запись должна создаваться сначала в таблице user, а потом благодаря cascade добавляться в таблицу authority. Очевидно я что-то упускаю из вида. Прошу помочь. Здесь SQL код для создания таблиц:
CREATE TABLE users (
id int NOT NULL AUTO_INCREMENT,
username varchar(30) NOT NULL unique,
password varchar(30),
enabled tinyint(1),
vote_id int,
PRIMARY KEY (id),
FOREIGN KEY (vote_id) REFERENCES vote_db.votes(id));
CREATE TABLE roles (
id int NOT NULL AUTO_INCREMENT,
role varchar(30) NOT NULL unique,
PRIMARY KEY (id));
CREATE TABLE authorities (
username varchar(30),
authority varchar(25),
FOREIGN KEY (username) REFERENCES users(username) on update cascade on delete cascade,
FOREIGN KEY (authority) REFERENCES roles(role) on update cascade on delete cascade);
Мой класс User
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Column(name = "enabled")
private boolean enabled;
@ManyToMany
@JoinTable(name = "authorities"
, joinColumns = @JoinColumn(name = "username")
, inverseJoinColumns = @JoinColumn(name = "authority"))
private Set<Role> roles;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "vote_id")
@JsonBackReference
private Vote vote;
public User() {
}
public User(String name, String password, Role... roles) {
this.username = name;
this.password = password;
this.roles = new HashSet<>(Arrays.asList(roles));
}
Getters и Setters я опускаю что бы не захламлять, там ничего имеющего отношение к вопросу нет.
Мой класс Role:
@Entity
@Table(name = "roles")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)`введите сюда код`
@Column(name = "id")
private int id;
@Column(name = "role")
private String role;
@ManyToMany
@JoinTable(name = "authorities"
, joinColumns = @JoinColumn(name = "authority")
, inverseJoinColumns = @JoinColumn(name = "username"))
private Set<User> users;
public Role() {
}
public Role(String role) {
this.role = role;
}
Мой Controller (только метод createUser() так как остальные методы работают с другими сущностями и с ними нет проблем):
@RestController
@RequestMapping("/admin/users")
public class AdminUserRestController {
private final UserService userService;
private final RoleService roleService;
public AdminUserRestController(UserService userService, RoleService roleService)
{
this.userService = userService;
this.roleService = roleService;
}
@PostMapping`
public User createUser(@RequestBody User user) {
return userService.createUser(user);
}
UserService и RoleService стандартны, просто возвращают данные полученные из репозитория (extends JpaRepository, без своей логики)