2017-09-24 30 views
2

私にはUserRoomという2つのモデルがあります。ユーザーは多数の部屋に所属し、部屋には多数のユーザーがいます。
は現在、私は私が見つけるか、彼を作成するのいずれか、モデルdddの多対多の関係

public class User extends BasePersistable { 

    private static final long serialVersionUID = 1492535311821424305L; 

    @Column(nullable = false, unique = true) 
    private String login; 

    @Column(nullable = false) 
    private Integer uid; 

    @ManyToMany(targetEntity = Room.class) 
    @JoinTable(name = "room_users", joinColumns = {@JoinColumn(name = "user_id")}, inverseJoinColumns = {@JoinColumn(name = "room_id")}) 
    private Set<Room> rooms = new HashSet<>(); 

public class Room extends AbstractAggregateRoot implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @JsonIgnore 
    private Long id; 

    @ManyToMany(mappedBy = "rooms", targetEntity = User.class, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}) 
    @JsonIgnore 
    private Set<User> users = new HashSet<>(); 

ユーザーがログイン

を持っている、と私はいくつかのルールに基づいて、彼のために部屋を見つけるか、または作成します。
私にとっては、2つのことがきわめて明確です。
1)部屋には多くのメッセージがあり、メッセージは部屋なしでは存在しないため、部屋は総計ルートです。
2)ユーザーは部屋の範囲外で操作する必要があるため、ユーザーは集約ルートでもある必要があります。

ここで問題が発生します。私は、集計ルートが別の集計ルート(値オブジェクトのみを参照)を参照していないことを知りました。集約ルートには、外部ソースに依存せずに存在する必要があるすべてのものが含まれている必要があります(この場合、User aggregate root)。

どうすればこれらの関係を作成できますか?ユーザーがログインした後、私は彼のために作成する必要がある部屋をどのように作成できますか?私はイベントを公開し、これに基づいて(UserCreatedEvent)部屋を作ったと思っていました...私は正しい方向にいますか?

答えて

2

はい、正しい方向です。

複数の集約にまたがるプロセスの場合は、Saga/Process managerを使用できます。このコンポーネントは、関連するイベント(つまり、UserCreatedEvent)を聞いて動作し、関連する集約にコマンドを送信します。あなたの場合、Sagaは、作成する必要があるすべての部屋に対して1つ以上のCreateRoomコマンドを送信します。

このプロセスは最終的に一貫していることに注意してください。つまり、イベントが送信されてからコマンドが送信されるまでに時間がかかります。

1

私はそれを見て、ユーザーはどの部屋にもありません。しかし、彼は、部屋に発表されたすべてのメッセージを受信するために予約購読を持っているかもしれません。サブスクリプションは、ユーザーとルーム間のメディエータとして作成できます。そして、それらは使い果たして、そのために削除することができます。彼らが運ぶ唯一の情報は、部屋とユーザーとの関係(そしておそらく有効期間)であり、IDは値オブジェクトなのでIDはありません。

部屋を参照するのを避けたいが、その間に値オブジェクトがある場合は、サブスクリプションがあなたに代わってくれます。

+0

これは本当にいい方法です...私はそれで寝るでしょう、私は何ができるか見てみましょう!しかし、1つの質問:彼らはIDがない場合、どのように私はこの関係を構築することができます...私は間違いなくこの情報を保存する必要があります... –

+1

あなたは@ ElementCollectionを見てください。これがあなた(またはあなたのeclipse jpaプラグインがあなたのプロジェクト全体にエラーでいっぱいになる)のためにうまくいかない場合でも、それをJPAエンティティとしてモデル化できます。ちょうど何かがデータベースにそれを格納するための技術的なIDを持っていても、あなたのドメインにIDを持っているわけではありません。 ... idフィールドをプライベートにして、setter/getter -methodsをidに追加しないでください。 – EasterBunnyBugSmasher