java - JPA,如何将 Map 中实体类型的值添加到主键?
问题描述
我有 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 的解决方案,以便代码自行管理
解决方案
我认为您没有正确建模您的概念。你有一个ManyToMany
介于两者之间的东西Role
,Priviledge
但是是什么构成UrlMapper
了一个实体?您有一个Map<Role, Privilege>
字段,UrlMapper
但这是连接表的目的,因此不需要复制它。相反,它似乎是这种HttpMethod
关系Path
的属性。
但是,我可能还注意到,您似乎期望有许多不同的 HttpMethod/Path 组合的角色/权限连接。这似乎令人难以置信的细粒度和操作噩梦,但无论如何。无论如何,您似乎在说的是您想要角色/特权/HttpMethod/Path 的独特组合,因此您应该为此创建一个实体,并且该表代表您的集合。创建一个拥有唯一角色/权限/HttpMethod/Path 的权限实体。Role、Privilege、HttpMethod 甚至 Path 本质上都是枚举,因此您应该为每个枚举都有一个表,并ManyToOne
在 Permission 实体中进行映射。您可以在每个查找表中添加双向OneToMany
映射,但我不确定是否需要这样做。由你决定。
我假设Privilege
会是 {allow, deny} 但如果您假设拒绝,除非明确存在 Role/HttpMethod/Path 权限,否则它似乎不那么纠结。如果是这种情况,那么我会忽略该Privilege
实体。无论如何,只是一个想法。希望这可以帮助。
推荐阅读
- php - PHP 语法 ?>
我无法弄清楚 ?> <? 此代码中正在执行语法。我已经搜索了 php 语法页面,这不是一个开始或结束标记,也不是一个简短的打开标记。没有它,代码将无法编译,并且我在后面的大括号中得到了一种奇怪的颜色。
if(isset($_POST)){?> <form method="POST" action="Form_Index.php">
- android - 在同步函数中等待异步结果
- sql-server - Get-SqlErrorLog 电子邮件备份失败
- html - 如何从 html 文档中批量删除此处的整个文本
- flutter - 当您返回更改第一个下拉菜单时,取决于 Dropdown 失败断言错误
- python - 为什么我实现的mergeSort有O(n^2)?
- flutter - 如何在 Flutter 中使用 ListTile 显示列内的项目列表
- gnuradio - gnuradio 标记流到 PDU 块中缺少长度标记
- typescript - Jest 和 Typescript:覆盖默认模拟实现的推荐方法
- ios - Swift:枚举 Int,可编码用于各种情况