Hibernate Spring OneToMany - ManyToOne领域驱动设计

时间:2017-08-30 04:39:28

标签: java hibernate domain-driven-design

我有2个实体“用户”和“组”。实际上这是一个ManyToMany关联,但我想在关系表中保留额外的信息,比如created或userid。

所以我发现我必须引入一个代表关系表“UserGroup”的新实体。

表格:

用户 id,name,pw

群组 ID,名称

usergroup id,userid,groupid,created,createduserid

实体:

@Entity
@Table(name="user")
public class User {
  @OneToMany(mappedBy="user")
  List<UserGroup> groups;
}

@Entity
@Table(name="group")
public class Group {
  @OneToMany(mappedBy="group")
  List<UserGroup> users;
}

@Entity
@Table(name="usergroup")
public class UserGroup {
  @ManyToOne
  User user;

  @ManyToOne
  User group;

  @Column(name="created")
  Date created;

  // ...
}

现在由于Domain Driven Design,我不得不介绍 在我的用户实体方法中,例如:User :: addGroup(group),User :: removeFromGroup(group)。 但从技术上讲,这似乎是不可能的,因为我需要创造 一个UserGroup实体,注入User和Group对象并最终持久化 它与EntityManager。

是否有更优雅的解决方案,或者我是否真的必须在服务对象的实体之外执行此操作?

(使用ManyToMany,我可以在实体中执行此操作。)

2 个答案:

答案 0 :(得分:5)

您使用&#34;实体表&#34;开始了您的域名描述。和&#34;表之间的关系&#34;这绝不是DDD方法。您必须将您的域名取消,并忽略持久性,就好像所有对象都存储在内存中一样。

此外,您需要在代码中使用来自无处不在的语言的术语,例如替换&#34; UserGroup&#34;与&#34;会员资格&#34;。

您不应引用其他aggregate rootGroup)中的aggregate rootUser)。即使是临时引用,我也不会这样做,因为它会向引用者移动关于引用的不必要的知识。 You can only reference by ID。因此,您的代码应如下User::addGroupMembership(groupId),并在内部创建new Membership实例。

  

是否有更优雅的解决方案,或者我真的必须这样做   我的实体在服务对象之外的操作?

如果您通过域服务进行此关联,则会有anemic domain model

答案 1 :(得分:0)

让我指出Vaughn Vernon在用户和群体之间设计这种关系时的优秀例子:

https://github.com/VaughnVernon/IDDD_Samples/tree/master/iddd_identityaccess/src/main/java/com/saasovation/identityaccess/domain/model/identity

如前所述,如果您使用表之间的关系对对象进行建模,那么您做错了。请参阅他的样本中使用的Vaughn概念,以了解他如何模拟用户属于某个群组的事实。