数据库:
我有一个名为Users_Accounts_Roles
的三向连接表。
+--------------+------------+------+-----+-------------------+----------------+
| 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 | |
+--------------+------------+------+-----+-------------------+----------------+
用户可以属于多个帐户,并且每个帐户可以拥有多个角色。
我还有User
表
+----------------+--------------+------+-----+---------------------+-----------------------------+
| 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 | |
+----------------+--------------+------+-----+---------------------+-----------------------------+
Account
表
+--------------+-------------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------------------+-----------------------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
+--------------+-------------+------+-----+---------------------+-----------------------------+
和Role
表
+--------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------------------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| description | text | NO | | NULL | |
+--------------+--------------+------+-----+---------------------+----------------+
对象(稀疏地):
@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;
...
}
我希望User.accounts
在数据库中提取Users_Accounts_Roles
时填充User
中的数据,但我不希望更改User.accounts
影响Users_Accounts_Roles
当User
持续存在时,Account.users
的更新。同样,我希望在从数据库中提取帐户时使用Users_Accounts_Roles
中的数据填充Accounts.users
,但我不希望更改Users_Accounts_Roles
来影响{{1}的更新当Account
被持久化时。 Users_Accounts_Roles
表格应该更改的唯一方法是User
是否与更新的accountRoles
字段保持一致。
按原样,User.accountRoles
映射正在按照我的喜好(从Users_Accounts_Roles
检索并持久保存),但我找不到User.accounts
和{{1}的方法分别在Account.users
和User
抓取时检索,但在Account
或User
持久化时不会保留,而不在DAO层中使用某些丑陋的逻辑。 (它们目前被标记为瞬态,因为我没有尝试过任何其他工作)。 Hibernate / JPA是否支持我正在尝试做的事情?
- - - - - - - - 编辑
我怀疑我的解决方案可能涉及在Account
和@OneToMany(mappedBy="...")
上使用User.accounts
,如同this tutorial中所做的那样。但是,我无法弄清楚如何对Account.users
和AccountRole
字段中的字段进行注释,以便对后者的更改仍然保留。
答案 0 :(得分:0)
您可以尝试使用user.accounts
将@ManyToMany
映射为@JoinTable(name ="Users_Accounts_Roles", joinColumns=...)
。默认情况下,@*ToMany
不会级联任何内容,因此您不会冒错误添加/删除条目。但是,修改Account
本身将被保留,但这只是因为它们是托管实体。无论如何,那些Account
对象将与通过user.accountRoles
集合链接的对象相同,所以我想这应该不是问题。
注意这种解决方案的性能,因为它可能导致执行大量查询(例如,为每个用户提取一个额外的查询以获取他的帐户)。
或者你可以简单地实现一个(只读)Collection<Account>
包装器,它将所有调用委托给user.accountRoles
集合(只需在getAccount()
个对象上调用AccountRole
它返回)。这样您就可以控制每个操作,并确保只获取一次关系。