Domain driven design 在ddd上建立多对多关系模型

Domain driven design 在ddd上建立多对多关系模型,domain-driven-design,Domain Driven Design,我有两种型号:User和Room。一个用户属于多个房间,一个房间有多个用户。 目前我有 public class User extends BasePersistable { private static final long serialVersionUID = 1492535311821424305L; @Column(nullable = false, unique = true) private String login; @Column(nullable = fa

我有两种型号:
User
Room
。一个用户属于多个房间,一个房间有多个用户。
目前我有

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<>();
公共类用户扩展BasePersistable{
私有静态最终长serialVersionUID=149253511821424305L;
@列(nullable=false,unique=true)
私有字符串登录;
@列(nullable=false)
私有整数uid;
@多人(targetEntity=Room.class)
@JoinTable(name=“room\u users”,joinColumns={@JoinColumn(name=“user\u id”)},inverseJoinColumns={@JoinColumn(name=“room\u id”)})
私有集房间=新HashSet();

公共教室扩展AbstractAggregateRoot实现可序列化{
私有静态最终长serialVersionUID=1L;
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@杰索尼奥雷
私人长id;
@ManyToMany(mappedBy=“rooms”,targetEntity=User.class,cascade={CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REMOVE})
@杰索尼奥雷
private Set users=new HashSet();
当用户登录时,我会查找或创建他,然后根据一些规则为他查找或创建房间。
对我来说,有两件事非常清楚:
1) 一个文件室有许多消息,没有文件室消息就不存在,因此,文件室是聚合根。
2) 用户需要在文件室的范围之外进行操作,因此,用户也应该是聚合根

所以问题来了:我知道聚合根不引用另一个聚合根(仅通过值对象)。聚合根应该包含它需要存在的所有内容,而不依赖于外部源(在本例中为用户聚合根)


我怎样才能在他们之间建立这种关系?在用户登录后,我怎样才能创建我需要为他创建的房间?我想我可以发布一个事件,然后根据这个(
UserCreatedEvent
)创建房间……我的方向对吗?

是的,你的方向对

对于跨多个聚合的进程,您可以使用。此组件通过侦听相关事件(即
UserCreatedEvent
)工作,并向相关聚合发送命令。在您的情况下,Saga将为需要创建的每个房间发送一个或多个
CreateRoom
命令


您应该记住,此过程最终是一致的,即从事件发出到命令发送之间有一个时间延迟。

在我看来,用户不在任何文件室中。但他可能有一个订阅来接收文件室中发布的所有消息。订阅可以作为用户和r之间的中介创建OOM。它们可以用完并因此被删除。它们携带的唯一信息是与房间和用户的关系(可能还有有效期),它们没有id,因为它们只是这个值对象


如果您不想让用户引用房间,但中间有一个值对象,那么订阅可能会帮您解决问题。

这是一个非常好的方式……我会仔细考虑一下,看看我能做些什么!但有一个问题:如果他们没有id,我如何建立这种关系……我的意思是,我肯定需要保存这些信息…您应该看看@ElementCollection。如果这不适合您(或者您的eclipse jpa插件导致整个项目充满错误),您仍然可以将其建模为一个JPA实体。仅仅因为某些东西有一个技术id来存储在数据库中,并不意味着它在您的域中有一个id…您可以将id字段设置为私有,而不向id添加setter/getter方法。
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<>();