2011-11-29 24 views
4

數據庫:配置Hibernate來抓取集合,而不將它保持

我有一個三路連接的表稱爲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_RolesUser是從數據庫中獲取,但我不想改變User.accountsUser被持久影響更新Users_Accounts_Roles。同樣,我希望Account.users在從數據庫中提取帳戶時使用Users_Accounts_Roles中的數據填充,但我不希望更改Accounts.users影響Users_Accounts_Roles的更新,當Account持久存在時。 Users_Accounts_Roles表應該更改的唯一方法是如果User持續更新accountRoles字段。

不變,那麼User.accountRoles映射工作,我喜歡的(無論是從檢索並持續到Users_Accounts_Roles),但我不能爲User.accounts找到一種方法和Account.users到在UserAccount取檢索,分別,但不持續存在UserAccount,而不在DAO層中使用某些難看的邏輯。 (他們目前被標記爲瞬態,因爲沒有其他的我嘗試工作)。 Hibernate/JPA支持我想要做什麼?

----- -----編輯

我懷疑爲this tutorial做我的解決方案可以使用@OneToMany(mappedBy="...")User.accountsAccount.users涉及。然而,我不知道如何註釋AccountRoleUser.accountRoles字段中的字段,以便對後者的更改仍然存在。

回答

0

您可以嘗試使用@JoinTable(name ="Users_Accounts_Roles", joinColumns=...)user.accounts@ManyToMany進行映射。默認情況下,@*ToMany不會級聯任何內容,因此您不會錯誤地添加/刪除條目。但是,修改Account本身將會持續存在,但這只是由於它們是管理實體。無論如何,那些Account對象將通過user.accountRoles集合鏈接相同,所以我想這不應該是一個問題。

注意這種解決方案的性能,因爲它可能導致執行大量查詢(例如,每個用戶爲獲取其賬戶提供一個附加查詢)。

或者你可以簡單地實現(只讀)Collection<Account>包裝,將委託給user.accountRoles集合其所有的呼叫(只要求它返回AccountRole對象getAccount())。這樣你就可以控制每一個操作,並且確保關係只被提取一次。