gpt4 book ai didi

java - 配置 hibernate 以检索集合而不持久化它

转载 作者:搜寻专家 更新时间:2023-11-01 03:55:29 25 4
gpt4 key购买 nike

数据库:

我有一个名为 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 | |
+--------------+-------------+------+-----+---------------------+-----------------------------+

还有一个角色

+--------------+--------------+------+-----+---------------------+----------------+
| 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 时,我希望用 Users_Accounts_Roles 中的数据填充 User.accounts,但我不这样做当 User 被持久化时,不希望对 User.accounts 的更改影响对 Users_Accounts_Roles 的更新。同样,当从数据库中获取帐户时,我希望使用 Users_Accounts_Roles 中的数据填充 Account.users,但我不想更改 Accounts .users 影响 Users_Accounts_Roles 的更新,当 Account 被持久化时。 Users_Accounts_Roles 表应该更改的唯一方法是,如果 User 与更新的 accountRoles 字段保持一致。

照原样,User.accountRoles 映射符合我的喜好(从 Users_Accounts_Roles 检索和持久化),但我找不到方法 User.accountsAccount.users 分别在 UserAccount 获取时检索,但在UserAccount 被持久化,没有在 DAO 层使用一些丑陋的逻辑。 (它们目前被标记为 transient ,因为我尝试过的其他方法都不起作用)。 Hibernate/JPA 是否支持我正在尝试做的事情?

-----编辑-----

我怀疑我的解决方案可能涉及在 User.accountsAccount.users 上使用 @OneToMany(mappedBy="...")正如在 this tutorial 中所做的那样.但是,我无法弄清楚如何注释 AccountRoleUser.accountRoles 字段中的字段,以便仍然保留对后者的更改。

最佳答案

您可以尝试映射 user.accounts@ManyToMany , 使用 @JoinTable(name ="Users_Accounts_Roles", joinColumns=...) .默认 @*ToMany不会级联任何东西,因此您不会冒错误添加/删除条目的风险。但是,修改 Account的本身将被持久化,但这只是因为它们是托管实体。不管怎样,那些Account对象将与通过 user.accountRoles 链接的对象相同集合,所以我想这应该不是问题。

请注意此类解决方案的性能,因为它可能会导致执行大量查询(例如,为每个用户额外查询一次以获取其帐户)。

或者,您可以简单地实现一个(只读)Collection<Account>将所有调用委托(delegate)给 user.accountRoles 的包装器集合(只需在返回的 getAccount() 对象上调用 AccountRole)。这样您就可以控制每个操作,并确保只获取一次关系。

关于java - 配置 hibernate 以检索集合而不持久化它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8318958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com