JPA,如何将Map中实体类型的值添加到主键?

时间:2019-06-30 08:33:23

标签: java mysql spring hibernate jpa

我有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

}

创建的键(主键和外键)如下

enter image description here

表生成时的日志如下:-

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的解决方案,以便代码自己对其进行管理

1 个答案:

答案 0 :(得分:1)

我认为您没有正确建模概念。您在ManyToManyRole之间有一个Priviledge,但是什么使UrlMapper成为实体?您在Map<Role, Privilege>中有一个UrlMapper字段,但这是联接表的目的,因此无需重复该操作。相反,似乎HttpMethodPath是关系的属性。

enter image description here

但是,我可能还会注意到,您似乎期望许多不同的HttpMethod / Path组合都具有Role / Privilege连接。这似乎令人难以置信的细粒度和操作噩梦,但无论如何。无论如何,您似乎要说的是想要Role / Privilege / HttpMethod / Path的唯一组合,因此您应该为此创建一个实体,并且该表表示您的集合。创建一个拥有唯一的Role / Privilege / HttpMethod / Path的Permission实体。 Role,Privilege,HttpMethod甚至Path本质上都是枚举,因此您应该为每个表创建一个表,并在Permission实体中使用ManyToOne映射。您可以在每个查询表中添加双向OneToMany映射,但是我不确定是否需要这样做。由你决定。

enter image description here

我假设Privilege将是{allow,deny},但如果您拒绝,除非明确存在Role / HttpMethod / Path权限,否则似乎有点纠结。如果是这种情况,那么我将省略Privilege实体。无论如何,只是一个想法。希望这会有所帮助。