【问题标题】:Hibernate Spring OneToMany - ManyToOne Domain Driven DesignHibernate Spring OneToMany - 多对一领域驱动设计
【发布时间】:2017-08-30 04:39:28
【问题描述】:

我有 2 个实体“用户”和“组”。实际上这是一个多对多关联,但我想在关系表中保留其他信息,例如 created 或 userid。

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

表格:

用户 ID、姓名、密码

ID、名称

用户组 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;

  // ...
}

现在由于领域驱动设计,我不得不介绍 在我的用户实体方法中,例如:User::addGroup(group)、User::removeFromGroup(group)。 但从技术上讲,这似乎是不可能的,因为我需要创建 一个 UserGroup 实体,注入 User 和 Group 对象,最后持久化 使用 EntityManager。

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

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

【问题讨论】:

  • 正如康斯坦丁所指出的,在这里您没有解释域,也没有拆分聚合根。在考虑“表格”之前,您需要充分了解您正在建模的领域。无论如何,您可以简单地通过创建一个嵌入式集合来实现您的要求,其中您拥有使用“userId、groupId created、useridCreated”构建的实体(以 ORM 术语)。看这里:java2s.com/Tutorials/Java/JPA/…, en.m.wikibooks.org/wiki/Java_Persistence/ElementCollection

标签: java hibernate domain-driven-design


【解决方案1】:

您以“实体表”和“表之间的关系”开始您的域描述,这绝不是 DDD 方法。您必须向我们描述您的域并忽略持久性,就好像所有对象都存储在内存中一样。

此外,您需要在代码中使用通用语言中的术语,例如将“UserGroup”替换为“Membership”。

您不应从另一个 aggregate root (User) 引用 aggregate root (Group)。即使是临时参考,我也不会这样做,因为它会将不必要的知识转移到参考者身上。 You can only reference by ID。所以你的代码应该看起来像这样User::addGroupMembership(groupId) 并在内部创建一个newMembership 实例。

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

如果您将域中的这种关联设为服务,您将拥有anemic domain model

【讨论】:

    【解决方案2】:

    让我指出 Vaughn Vernon 在设计用户和组之间的这种关系时的出色示例:

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

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

    【讨论】:

    • 我建议你给出一个更直接的答案,指出用户可以去查看实际示例的文件和方法。您只是显示了一个包含近 40 个 java 文件的列表,这有点令人沮丧并且可能很耗时。
    猜你喜欢
    • 2011-10-06
    • 2011-05-26
    • 2015-01-06
    • 1970-01-01
    • 2015-05-17
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多