2011-11-29 22 views
4

データベースは持続せずにコレクションを取得するために休止状態。の設定は、それが

+--------------+------------+------+-----+-------------------+----------------+ 
| 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がデータベースからフェッチされ、私はUserが永続化されたときにUser.accountsへの変更は、Users_Accounts_Rolesへの更新に影響を与えたくないときUser.accountsUsers_Accounts_Roles内のデータが取り込まれたいです。同様に、Account.usersにはUsers_Accounts_Rolesというデータが入力されますが、アカウントがデータベースから取得されたときにAccountが保持されている場合、Accounts.usersへの変更がUsers_Accounts_Rolesへの更新に影響しないようにします。 Userが更新されたaccountRolesフィールドで永続化されている場合は、Users_Accounts_Rolesテーブルを変更する唯一の方法です。

は通りであり、User.accountRolesマッピングは、(両方から検索し、Users_Accounts_Rolesに永続化)私の好みに合わせて取り組んでいるが、私はUserAccountフェッチ時に取得されるUser.accountsAccount.usersための方法を見つけることができない、それぞれはなく、 UserまたはAccountが持続されても、DAOレイヤーで醜いロジックを使用することなく持続されます。 (私は現在、何も作業をしていないので、Transientとしてマークされています)。私がやろうとしていることをHibernate/JPAがサポートしていますか?

----- ----- EDIT

私はthis tutorialに行ったように私の解決策はUser.accountsAccount.users@OneToMany(mappedBy="...")を使用することを含むことが疑われます。しかし、AccountRoleUser.accountRolesフィールドのフィールドに注釈を付ける方法を理解することはできません。後者への変更は依然として維持されます。

答えて

0

@JoinTable(name ="Users_Accounts_Roles", joinColumns=...)を使用して@ManyToManyuser.accountsをマッピングできます。デフォルトでは@*ToManyは何もカスケードしないので、誤って項目を追加/削除する危険はありません。しかし、Account自体の変更は永続化されますが、これは管理対象エンティティであるためです。とにかく、それらのAccountオブジェクトは、コレクションを通じてリンクされているものと同じになるので、これは問題ではないはずです。

多くのクエリを実行する可能性があるため、そのようなソリューションのパフォーマンスに注意してください(たとえば、アカウントを取得するユーザーごとに1つの追加クエリ)。

別の方法としては、単純に(ちょうどそれが返すAccountRoleオブジェクトにgetAccount()を呼び出す)user.accountRolesコレクションにすべての呼び出しを委任します(読み取り専用)Collection<Account>ラッパーを実装することができます。このようにして、すべての操作を制御し、リレーションが一度だけフェッチされるようにすることができます。

関連する問題