The problem is that with hibernade.ddl-auto: validate enabled, I get an error that the users_roles table does not exist: Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [users_roles] The table was registered in the db migration. Some kind of stupid mistake? I can't find the problem.
Migration code:
create schema if not exists zhem;
create table if not exists zhem.users
(
user_id bigserial primary key,
phone varchar(11) not null check ( phone similar to '79[0-9]{9}' ) unique,
password varchar(256) not null,
email varchar(256) check ( email similar to '([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)' ) unique,
first_name varchar(32) not null check ( length(trim(first_name)) >= 2 ),
last_name varchar(32) check ( length(trim(last_name)) >= 2 ),
created_at timestamp default now(),
updated_at timestamp default now()
);
create table if not exists zhem.roles
(
role_id serial primary key,
title varchar(32) not null check ( length(trim(title)) >= 2 ) unique
);
create table if not exists zhem.users_roles
(
user_role_id bigserial primary key,
user_id bigint not null references zhem.users (user_id),
role_id int not null references zhem.roles (role_id),
constraint unique_user_id_role_id unique (user_id, role_id)
);
Base entity:
@Data
@MappedSuperclass
public class BaseEntity {
@CreationTimestamp
@Column(name = "created_at")
private LocalDateTime createdAt;
@UpdateTimestamp
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}
User:
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(schema = "zhem", name = "users")
public class User extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@CheckPhoneNumber
@Column(name = "phone", unique = true)
private String phone;
@NotBlank
@Size(max = 256)
@Column(name = "password")
private String password;
@Email
@Size(max = 256)
@Column(name = "email", unique = true)
private String email;
@NotBlank
@Size(min = 2, max = 32)
@Column(name = "first_name")
private String firstName;
@Size(min = 2, max = 32)
@NullOrNotBlank
@Column(name = "last_name")
private String lastName;
@ManyToMany(fetch = FetchType.EAGER)
private Set<Role> roles;
}
Roles:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(schema = "zhem", name = "roles")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "role_id")
private Integer id;
@NotBlank
@Size(min = 2, max = 32)
@Column(name = "title", unique = true)
private String title;
}
application.yaml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/zhem-db
username: postgres
password: root
flyway:
schemas:
- public
- zhem
jpa:
hibernate:
ddl-auto: validate
I tried different ways to link the entity - Unidirectional, Bidirectional, Bidirectional many-to-many with link entity. Nothing changes, the table is still missing.
I think you should specify the @JoinTable
parameters to make Hibernate recognize your relation table users_roles
.
public class User extends BaseEntity {
//...
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
schema = "zhem",
name = "users_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
//...
}