Мне нужно поддержать сценарий, который включает следующие объекты (с использованием JPA):
- Пользователь
- Аккаунт
- Роль
Пользователь может иметь несколько учетных записей, и учетная запись может совместно использоваться несколькими пользователями, на данный момент это стандартное отношение @ManyToMany.
Пользователь может иметь различный набор ролей для каждой учетной записи, роль можетбыть доступным для нескольких пользователей.
Я следовал этой практике , которая объясняет способ сопоставления многих смного ассоциаций с дополнительными столбцами, но я не уверен, что получаю его.
сущность UserAccount:
@Entity
@Table(name = "users_accounts")
public class UserAccount implements Serializable {
@EmbeddedId
private UserAccountId id;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("userId")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("accountId")
private Account account;
private UserAccount() {}
public UserAccount(@NotNull User user, @NotNull Account account) {
this.user = user;
this.account = account;
this.id = new UserAccountId(user.getId(), account.getId());
}
//Getters Setters..
}
UserAccountId:
@Embeddable
public class UserAccountId implements Serializable {
@Column(name = "user_id")
private String userId;
@Column(name = "account_id")
private String accountId;
private UserAccountId() {
}
public UserAccountId(
String userId,
String accountId) {
this.userId = userId;
this.accountId = accountId;
}
//Getters Setters..
}
Сущность пользователя:
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
private String id;
@Column(name = "email", nullable = false)
private String email;
@Column(name = "full_name", nullable = false)
private String fullName;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<UserAccount> accounts;
public User() {
accounts = Sets.newHashSet();
}
public void addAccont(Account account) {
UserAccount userAccount = new UserAccount(this, account);
accounts.add(userAccount);
account.getUsers().add(userAccount);
this.accounts.add(userAccount);
}
public void removeAccont(Account account) {
for (Iterator<UserAccount> iterator = accounts.iterator(); iterator.hasNext(); ) {
UserAccount userAccount = iterator.next();
if (userAccount.getUser().equals(this) &&
userAccount.getAccount().equals(account)) {
iterator.remove();
userAccount.getAccount().getUsers().remove(userAccount);
userAccount.setUser(null);
userAccount.setAccount(null);
}
}
}
//Getters Setters..
}
Сущность счета:
@Entity
@Table(name = "accounts")
public class Account implements Serializable {
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
private String id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "billing_address", nullable = false)
private String billingAddress;
@OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<UserAccount> users;
public Account() {
users = Sets.newHashSet();
}
//Getters Setters..
}
Я могу легко добавить дополнительный столбец вкласс UserAccount
, но мне нужно добавить набор ролей для каждого UserAccount
, также можно назначить роль нескольким объектам UserAccount
, чтобы пользователь мог иметь другой набор ролейдля каждого из своих аккаунтов.Это правильно / имеет смысл?следует добавить в класс UserAccount
отношение @ManyToMany к Role
:
@Entity
@Table(name = "users_accounts")
public class UserAccount implements Serializable {
@EmbeddedId
private UserAccountId id;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("userId")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("accountId")
private Account account;
@ManyToMany(
fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(
name = "users_accounts_roles",
joinColumns = {
@JoinColumn(name = "user_id", referencedColumnName = "user_id"),
@JoinColumn(name = "account_id", referencedColumnName = "account_id"),
},
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
)
private Set<Role> roles;
private UserAccount() {}
public UserAccount(@NotNull User user, @NotNull Account account) {
this.user = user;
this.account = account;
roles = Sets.newHashSet();
this.id = new UserAccountId(user.getId(), account.getId());
}
//Getters Setters..
}