Database:
I have a three-way join table called Users_Accounts_Roles.
Code:
+--------------+------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------+------+-----+-------------------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| user_id | bigint(20) | NO | MUL | NULL | |
| account_id | bigint(20) | NO | | 0 | |
| role_id | bigint(20) | NO | | NULL | |
+--------------+------------+------+-----+-------------------+----------------+
Users can belong to multiple accounts and can have multiple roles for each of those accounts. I also have a User table
Code:
+----------------+--------------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------------------+-----------------------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| email | varchar(255) | NO | UNI | NULL | |
| firstName | varchar(255) | NO | | NULL | |
| lastName | varchar(255) | NO | | NULL | |
+----------------+--------------+------+-----+---------------------+-----------------------------+
an Account table
Code:
+--------------+-------------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------------------+-----------------------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
+--------------+-------------+------+-----+---------------------+-----------------------------+
and a Role table
Code:
+--------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------------------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| description | text | NO | | NULL | |
+--------------+--------------+------+-----+---------------------+----------------+
Objects (sparsely):
Code:
@Embeddable
AccountRole {
...
@Parent
User getUser() {
return user;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "account_id")
Account getAccount() {
return account;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "role_id")
Role getRole() {
return role;
}
...
}
@Entity
User {
...
@Transient
Set<Account> getAccounts() {
return accounts;
}
@ElementCollection(fetch = FetchType.EAGER)
@JoinTable(name = "Users_Accounts_Roles", joinColumns = @JoinColumn(name = "user_id"))
Set<AccountRole> getAccountRoles() {
return accountRoles;
}
...
}
@Entity
Account {
...
@Transient
Set<User> users;
...
}
I want User.accounts to be populated with the data in Users_Accounts_Roles when a User is fetched from the database, but I don't want changes to User.accounts to influence updates to Users_Accounts_Roles when a User is persisted. Similarly, I want Account.users to be populated with the data in Users_Accounts_Roles when an Account is fetched from the database, but I don't want changes to Accounts.users to influence updates to Users_Accounts_Roles when an Account is persisted. The only way the Users_Accounts_Roles table should change is if a User is persisted with an updated accountRoles field.
As is, the User.accountRoles mapping is working to my liking (both retrieving from and persisting to Users_Accounts_Roles), but I can't find a way for User.accounts and Account.users to be retrieved upon User and Account fetching, respectively, but not persisted when a User or Account is persisted, without using some ugly logic in the DAO layer. (They are currently marked as Transient since nothing else I tried worked). Does Hibernate/JPA support what I'm trying to do?
-----EDIT-----
I suspect my solution may involve using @OneToMany(mappedBy="...") on User.accounts and Account.users as done in
this tutorial. However, I can't figure out how to annotate the fields in AccountRole and the User.accountRoles field to make it so that changes to the latter are still persisted.