我有3个实体类,如下所示:-
角色实体
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToMany
@LazyCollection(LazyCollectionOption.FALSE)
@JoinTable(name = "roles_privileges", joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id"))
private Set<Privilege> privileges;
// getters, setters etc
}
特权实体
@Entity
public class Privilege {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(mappedBy = "privileges", fetch = FetchType.EAGER)
@JsonIgnore
private Set<Role> roles;
// getters, setters etc
}
UrlsMapper实体
@Entity(name = "urls_mapper")
@Table(name = "urls_mapper")
public class UrlsMapper {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.STRING)
@Column(name = "http_method")
private HttpMethod httpMethod;
@Column(name = "path")
private String path;
@ManyToMany(fetch = FetchType.EAGER)
@MapKeyJoinColumn(name = "role_id", referencedColumnName = "id")
@JoinTable(
name = "u_r_p",
inverseJoinColumns = @JoinColumn(name = "privilege_id")
)
Map<Role, Privilege> privilegeMap;
// getters, setters etc
}
创建的键(主键和外键)如下
表生成时的日志如下:-
Hibernate: create table u_r_p (urls_mapper_id bigint not null, privilege_id bigint not null, role_id bigint not null, primary key (urls_mapper_id, role_id)) engine=InnoDB
Hibernate: alter table u_r_p add constraint FKgd7gd9f9ded1s28swdudqs0ro foreign key (privilege_id) references Privilege (id)
Hibernate: alter table u_r_p add constraint FKrryprkx4j60lyjti16eysn5g5 foreign key (role_id) references Role (id)
Hibernate: alter table u_r_p add constraint FKfkthdnoca59a18ba96183p7ov foreign key (urls_mapper_id) references urls_mapper (id)
我只想知道如何将privilege_id也添加到JoinTable u_r_p中,以及是否还有其他最佳选择。手动在数据库中执行操作是一个明显的替代方法,但是我想知道基于hbm2ddl.auto的解决方案,以便代码自己对其进行管理
答案 0 :(得分:1)
我认为您没有正确建模概念。您在ManyToMany
和Role
之间有一个Priviledge
,但是什么使UrlMapper
成为实体?您在Map<Role, Privilege>
中有一个UrlMapper
字段,但这是联接表的目的,因此无需重复该操作。相反,似乎HttpMethod
和Path
是关系的属性。
但是,我可能还会注意到,您似乎期望许多不同的HttpMethod / Path组合都具有Role / Privilege连接。这似乎令人难以置信的细粒度和操作噩梦,但无论如何。无论如何,您似乎要说的是想要Role / Privilege / HttpMethod / Path的唯一组合,因此您应该为此创建一个实体,并且该表表示您的集合。创建一个拥有唯一的Role / Privilege / HttpMethod / Path的Permission实体。 Role,Privilege,HttpMethod甚至Path本质上都是枚举,因此您应该为每个表创建一个表,并在Permission实体中使用ManyToOne
映射。您可以在每个查询表中添加双向OneToMany
映射,但是我不确定是否需要这样做。由你决定。
我假设Privilege
将是{allow,deny},但如果您拒绝,除非明确存在Role / HttpMethod / Path权限,否则似乎有点纠结。如果是这种情况,那么我将省略Privilege
实体。无论如何,只是一个想法。希望这会有所帮助。