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<>();