简体   繁体   English

Hibernate Spring OneToMany - ManyToOne领域驱动设计

[英]Hibernate Spring OneToMany - ManyToOne Domain Driven Design

I have 2 Entities "User" and "Group". 我有2个实体“用户”和“组”。 Actually this is a ManyToMany association but I want to persist additional informations in the relation table like created or userid. 实际上这是一个ManyToMany关联,但我想在关系表中保留额外的信息,如created或userid。

So I found out that I have to introduce a new entity which represents the relation table "UserGroup". 所以我发现我必须引入一个代表关系表“UserGroup”的新实体。

The tables: 表格:

user id, name, pw 用户 ID,名称,pw

group id, name ID,名称

usergroup id, userid, groupid, created, createduserid usergroup id,userid,groupid,created,createduserid

The entities: 实体:

@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;

  // ...
}

Now due to Domain Driven Design I would have to introduce in my User Entity methods like: User::addGroup(group), User::removeFromGroup(group). 现在由于域驱动设计,我将不得不在我的用户实体方法中引入如下:User :: addGroup(group),User :: removeFromGroup(group)。 But technically this appears to be impossible because I need to create a UserGroup entity, inject the User and Group object and finally persist it with the EntityManager. 但从技术上讲,这似乎是不可能的,因为我需要创建一个UserGroup实体,注入User和Group对象,最后用EntityManager保存它。

Is there a more elegant solution or do I really have to do this operations outside of my entities in service objects? 是否有更优雅的解决方案,还是我真的必须在服务对象的实体之外执行此操作?

(With ManyToMany I can do this in the entities.) (使用ManyToMany,我可以在实体中执行此操作。)

You started your domain description with "entity tables" and "relations between tables" and that is not in any way a DDD approach. 您使用“实体表”和“表之间的关系”开始了您的域描述,这绝不是DDD方法。 You must dedcribe us your domain and ignore the persistence as if all the objects are stored in memory. 您必须将您的域取之,并忽略持久性,就好像所有对象都存储在内存中一样。

Also, you need to use, in code, terms from your ubiquitous language, for example replace "UserGroup" with "Membership". 此外,您需要在代码中使用来自无处不在的语言的术语,例如将“UserGroup”替换为“Membership”。

You should not reference an aggregate root ( Group ) from another aggregate root ( User ). 您不应该从另一个aggregate rootUser )引用aggregate rootGroup )。 I wouldn't do that even if is a temporary reference as it moves unnecessary knowledge to the referencer about the referenced. 即使是临时引用,我也不会那样做,因为它会向引用者移动不必要的知识。 You can only reference by ID . 您只能通过ID引用 So your code should look like this User::addGroupMembership(groupId) and internally create a new instance of Membership . 因此,您的代码应该看起来像User::addGroupMembership(groupId)并在内部创建一个newMembership实例。

Is there a more elegant solution or do I really have to do this operations outside of my entities in service objects? 是否有更优雅的解决方案,还是我真的必须在服务对象的实体之外执行此操作?

If you make this association from a domain a service you will have an anemic domain model . 如果您从域服务进行此关联,您将拥有贫血域模型

Let me point you to the excellent example of Vaughn Vernon when he designed such a relation between User and Group: 让我指出Vaughn Vernon在设计User和Group之间的这种关系时的优秀例子:

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

As mentionned before, if you model the objects with relations between tables, you are doing it wrong. 如前所述,如果使用表之间的关系对对象进行建模,则表明您做错了。 See the concept Vaughn used in his sample to understand how he modeled the fact a user belong to a group. 请参阅Vaughn在其示例中使用的概念,以了解他如何模拟用户属于某个组的事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM