【问题标题】:Configuring hibernate to retrieve a collection without persisting it配置休眠以检索集合而不持久化它
【发布时间】:2011-11-29 22:59:10
【问题描述】:

数据库:

我有一个名为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 在从数据库中获取User 时填充Users_Accounts_Roles 中的数据,但我不希望User.accounts 的更改影响Users_Accounts_Roles 的更新当@ 987654336@ 被保留。同样,当从数据库中获取帐户时,我希望用 Users_Accounts_Roles 中的数据填充 Account.users,但我不希望对 Accounts.users 的更改影响对 Users_Accounts_Roles 的更新,而 Account 是坚持。 Users_Accounts_Roles 表应该更改的唯一方法是,如果 User 使用更新的 accountRoles 字段保持不变。

照原样,User.accountRoles 映射按我的喜好工作(从Users_Accounts_Roles 检索和持续到Users_Accounts_Roles),但我找不到在@987654349 上检索User.accountsAccount.users 的方法@ 和 Account 分别获取,但当 UserAccount 被持久化时不会持久化,而在 DAO 层中没有使用一些丑陋的逻辑。 (它们目前被标记为瞬态,因为我没有尝试过其他任何工作)。 Hibernate/JPA 是否支持我正在尝试做的事情?

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

我怀疑我的解决方案可能涉及在User.accountsAccount.users 上使用@OneToMany(mappedBy="..."),就像在this tutorial 中所做的那样。但是,我不知道如何注释 AccountRoleUser.accountRoles 字段中的字段以使其保持对后者的更改。

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    您可以尝试使用@JoinTable(name ="Users_Accounts_Roles", joinColumns=...)user.accounts 映射到@ManyToMany。默认情况下,@*ToMany 不会级联任何内容,因此您不会冒险错误地添加/删除条目。但是,修改Account 本身将被保留,但这仅仅是因为它们是托管实体。无论如何,那些Account 对象将与通过user.accountRoles 集合链接的对象相同,所以我想这应该不是问题。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多