kakabali
kakabali

Reputation: 4033

JPA, How to add the value of entity type in Map to primary key?

I have 3 entity classes like below:-

Role Entity

@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

}

Privilege Entity

@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

@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

}

The keys, primary and foreign that get created are as below

enter image description here

The logs while table generation is as below:-

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)

And I just want to know how can I add the privilege_id also into the JoinTable u_r_p and if there can be other best options for this. Manually doing in the database is a obvious alternate, but i wanted to know the hbm2ddl.auto based solution, so that code manages it itself

Upvotes: 0

Views: 195

Answers (1)

K.Nicholas
K.Nicholas

Reputation: 11551

I don't think you've modeled your concepts properly. You have a ManyToMany between Role and Priviledge but what makes UrlMapper an entity? You have a Map<Role, Privilege> field in UrlMapper but that is the purpose of the join table so there should be no need to duplicate that. Instead it seems to be that HttpMethod and Path are attributes of the relationship.

enter image description here

However, I might also note that you seem to be expecting there be a Role/Privilege join for many different HttpMethod/Path combinations. This seems incredibly fine grained and an operations nightmare, but whatever. Anyway, what you seem to be saying is you want unique combinations of Role/Privilege/HttpMethod/Path so you should just make a entity for that and the table represents your set. Make a Permission entity that holds a unique Role/Privilege/HttpMethod/Path. Role, Privilege, HttpMethod, and even Path are essentially enumerations so you should have a table for each for each of them with ManyToOne mappings in the Permission entity. You could add bidirectional OneToMany mappings in each of the lookup tables but I'm not sure I see a need for that. It's up to you.

enter image description here

I assume Privilege would be {allow, deny} but it seems like less of a tangle if you assume deny unless a Role/HttpMethod/Path permission specifically exists. If that's the case then I would leave out the Privilege entity. Anyway, just a thought. Hope this helps.

Upvotes: 1

Related Questions