I had a lot of struggle with SQL scripts. Finally, I got them working fine. Then, out of pure interest, I dropped the tables and tried Hibernate's default schema creation (based on @Entity
mappings)
spring.jpa.hibernate.ddl-auto=update
-- I'll omit the population part to make it more MRE-ish
-- spring.sql.init.mode=always
-- spring.sql.init.data-locations=classpath:/sql/data.sql
Here's what I got
2023-04-20T06:02:20.227+03:00 WARN 1196 --- [ main] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL "create table users (id bigint not null auto_increment, age tinyint not null, department varchar(255) not null, email varchar(255), enabled tinyint not null, last_name varchar(255) not null, name varchar(255) not null, password varchar(255) not null, salary integer, username varchar(255) not null, primary key (id)) engine=InnoDB" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table users (id bigint not null auto_increment, age tinyint not null, department varchar(255) not null, email varchar(255), enabled tinyint not null, last_name varchar(255) not null, name varchar(255) not null, password varchar(255) not null, salary integer, username varchar(255) not null, primary key (id)) engine=InnoDB" via JDBC Statement
at
-- I'll skip a ton of presumably unhelpful lines to make it more MRE-ish
Caused by: java.sql.SQLException: Cannot add foreign key constraint
Why is that, and how do I avoid this error when choosing to rely on Hibernate's default schema creation? As you may have noticed no FKs were created by Hibernate's SQL statement (not explicitly, at least). Here are my @Entity
classes:
@Entity
@Table(name = "users")
@Getter
@Setter
@EqualsAndHashCode
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String name;
@Column(name = "last_name", nullable = false)
private String lastName;
@Column(nullable = false)
private String department;
@Column
private int salary;
@Column(nullable = false)
private byte age;
@Column
private String email;
@Column(name = "enabled", nullable = false)
private byte enabledByte;
@ManyToMany
@JoinTable(name = "user_role",
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id"),
@JoinColumn(name = "username", referencedColumnName = "username")},
inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id"),
@JoinColumn(name = "role", referencedColumnName = "role")})
@EqualsAndHashCode.Exclude
private Set<Role> authorities;
@Entity
@Table(name = "roles")
@Getter
@Setter
@EqualsAndHashCode
public class Role implements GrantedAuthority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "role", nullable = false, unique = true)
private String authority;
@ManyToMany(mappedBy = "authorities")
@EqualsAndHashCode.Exclude
private Set<User> userList;
I recall I executed this statement in my Workbench (here's why)
set foreign_key_checks=0;
It may be relevant
Just so you know, I read these questions (1, 2, 3, 4, 5) that mention the same exception. They don't appear helpful