JPA Many to Many with Intermediate Table and MapKey*

126 Views Asked by At

I'm struggling to setup the following JPA mapping (extra cols, etc. omitted for brevity)

----
id: primary key


organization
------------
id: primary key
z

role_assignment
---------------
role_assignment_id: primary key
user_id: fk -> user.id
organization_id: fk -> organization.id
role

(user_id, organization_id) is unique

The mapping needed would be on Organization class:

Map<User, RoleAssignment> roleAssignments

I can get close with something like:

class User {
  @Id
  @GeneratedValue
  private long id;
}

class RoleAssignment {
  @Id
  @GeneratedValue
  @Column(name = "role_assignment_id")
  private long id;

  @Column(name = "role")
  private String role;

  @ManyToOne
  @JoinColumn(name = "user_id")
  private User user;

  @ManyToOne
  @JoinColumn(name = "organization_id")
  private Organization organization;
}

class Organization {
  @Id
  @GeneratedValue
  private long id;

  @OneToMany(mappedBy = "user", orphanRemoval = true, cascade = CascadeType.ALL)
  @MapKey(name = "user")
  private Map<User, RoleAssignment> roleAssignments;
}

I've tried several configurations with MapKey, MapKeyJoinColumn, etc, and the best I get is a map with one null key mapped to a single value (despite multiple entries in the database).

Any help on setting this up would be greatly appreciated.

Update

I think I omitted some key info trying to be concise. The following paints a more clear picture:

----
id: primary key


organization
------------
id: primary key


role
----
id: primary key


role_assignment
---------------
role_assignment_id: primary key
user_id: fk -> user.id
organization_id: fk -> organization.id
role_id: fk -> role

(user_id, organization_id) is unique and can be made primary key if needed

The mapping needed would be on Organization class:

Map<User, RoleAssignment> roleAssignments

I can get close with something like:

class User {
  @Id
  @GeneratedValue
  private long id;
}

class RoleAssignment {
  // this could be converted to an @EmbeddedId if that helps
  @Id
  @GeneratedValue
  @Column(name = "role_assignment_id")
  private long id;

  @Column(name = "role")
  private String role;

  @ManyToOne
  @JoinColumn(name = "user_id")
  private User user;

  @ManyToOne
  @JoinColumn(name = "organization_id")
  private Organization organization;

  @ManyToOne
  @JoinColumn(name = "role_id")
  private Role role;
}

class Organization {
  @Id
  @GeneratedValue
  private long id;

  @OneToMany(mappedBy = "organization", orphanRemoval = true, cascade = CascadeType.ALL)
  @MapKey(name = "user") // <-- this is the piece I can't get to work
  private Map<User, RoleAssignment> roleAssignments;
}

I'm able to get a basic mapping to List<RoleAssignment> to work, but the logic of the rest of the application requires the Map mapping I described.

0

There are 0 best solutions below