Estoy usando Spring Boot 2 y PostGres 10. He creado las siguientes entidades, Roles y Privilegios,
@Data @Entity @Table(name = "Roles") public class Role { public enum Name { USER, ADMIN } @Id @GeneratedValue(strategy = GenerationType.AUTO) private UUID id; @Column(unique=true) @Enumerated(EnumType.STRING) private Name name; @ManyToMany @JoinTable( name = "roles_privileges", joinColumns = @JoinColumn( name = "role_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn( name = "privilege_id", referencedColumnName = "id")) private Collection<Privilege> privileges; }El privilegio es
@Data @Entity @Table(name = "Privileges") public class Privilege { public enum PrivilegeName { SUPER_ADMIN, USER } @Id @GeneratedValue(strategy = GenerationType.AUTO) private UUID id; @Column(unique=true) @Enumerated(EnumType.STRING) private PrivilegeName name; @ManyToMany(mappedBy = "privileges") private Collection<Role> roles; }Entonces tengo esto en mi application.properties
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.show-sql=true spring.datasource.url=jdbc:postgresql://${PG_DB_HOST:localhost}:5432/${PG_DB_NAME} spring.datasource.username=${PG_DB_USER} spring.datasource.password=${PG_DB_PASS}Cuando se generan mis tablas, la tabla roles_privileges se genera así...
cardmania=# \d roles_privileges ; Table "public.roles_privileges" Column | Type | Modifiers --------------+------+----------- role_id | uuid | not null privilege_id | uuid | not null Foreign-key constraints: "fk5duhoc7rwt8h06avv41o41cfy" FOREIGN KEY (privilege_id) REFERENCES privileges(id) "fk629oqwrudgp5u7tewl07ayugj" FOREIGN KEY (role_id) REFERENCES roles(id)¿Hay otras anotaciones u otro código Java que pueda agregar para que cuando se cree mi tabla de unión, el role_id/privilege_id tenga una clave única generada?
Para obligar a Hibernate a crear una clave principal con ambas columnas, debe cambiar Collection by Set
public class Role { @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @JoinTable( name = "roles_privileges", joinColumns = @JoinColumn( name = "role_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn( name = "privilege_id", referencedColumnName = "id")) private Set<Privilege> privileges; }Y:
public class Privilege { @ManyToMany(mappedBy = "privileges") private Set<Role> roles; } create table roles_privileges ( role_id binary not null, privilege_id binary not null ) @ManyToMany @JoinTable( name = "roles_privileges", joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn( name = "privilege_id", referencedColumnName = "id"), uniqueConstraints = @UniqueConstraint(columnNames = {"role_id", "privilege_id"}, name = "rolesPrivilegesConstraint") ) private Collection<Privilege> privileges;