我有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,我可以在实体中执行此操作。)
答案 0 :(得分:5)
您使用&#34;实体表&#34;开始了您的域名描述。和&#34;表之间的关系&#34;这绝不是DDD方法。您必须将您的域名取消,并忽略持久性,就好像所有对象都存储在内存中一样。
此外,您需要在代码中使用来自无处不在的语言的术语,例如替换&#34; UserGroup&#34;与&#34;会员资格&#34;。
您不应引用其他aggregate root
(Group
)中的aggregate root
(User
)。即使是临时引用,我也不会这样做,因为它会向引用者移动关于引用的不必要的知识。 You can only reference by ID。因此,您的代码应如下User::addGroupMembership(groupId)
,并在内部创建new
Membership
实例。
是否有更优雅的解决方案,或者我真的必须这样做 我的实体在服务对象之外的操作?
如果您通过域服务进行此关联,则会有anemic domain model。
答案 1 :(得分:0)
让我指出Vaughn Vernon在用户和群体之间设计这种关系时的优秀例子:
如前所述,如果您使用表之间的关系对对象进行建模,那么您做错了。请参阅他的样本中使用的Vaughn概念,以了解他如何模拟用户属于某个群组的事实。