DDD聚合ID和外键

时间:2014-02-08 01:11:28

标签: java domain-driven-design

我对DDD很新。我已经看到了许多使用泛型AggregateId(带有包含GUID的String)作为聚合根的键的示例项目。

我想知道如何在OneToMany关系中引用子节点的aggregateRoot。

假设有一个Order AggregateRoot和一个OrderLine。在GUID旁边有一个额外生成的(例如序列)id是否明智,所以OrderLine可以在数据库级别引用它?或者是orderLine的外键来订购GUID?是否有性能影响?

例如

BaseAggregateRoot:

@MappedSuperclass  
public abstract class BaseAggregateRoot {
    @EmbeddedId
    @AttributeOverrides({
       @AttributeOverride
       (name = "idValue", column = @Column(name = "aggregateId", nullable = false))
    })
    protected AggregateId aggregateId;
    ...

订单:

@Entity
public class Order extends BaseAggregateRoot{
    // is this ID necessary?
    @Id
    @GeneratedValue(generator = "OrderSequenceGenerator")
    @SequenceGenerator(name = "OrderSequenceGenerator", sequenceName = "ORD_SEQ1", allocationSize = 1)
    @Column(name = "ord_seq")
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "aggregateId")  <-- should this point to ID or aggregateId?
    private List<OrderLine> orderLines;

1 个答案:

答案 0 :(得分:1)

首先,我想澄清DDD是关于域建模的,并且与 域的持久性无关。它可能存在于数据库中,但也可能存在于文本文件中。从域建模的角度来看,实体与其他实体相关的实体(以及如何)很重要,但通常不关联它们在关系数据库中的相关性。也就是说,问销售代表。订单项目如何识别其所属的订单,他会问你回报你的错误。

性能方面,使用GUID作为密钥存在一些风险。随机生成的GUID不适用于聚簇索引。最好使用顺序生成算法,并让数据库为您提供这些GUID。以下是有关此主题的讨论的链接:

What are the performance improvement of Sequential Guid over standard Guid?

我建议你特别阅读this answer。我同意Dan的观点,即连续的GUID缺少重点。

从关系上讲,对同一记录有两个标识符似乎是不必要的,而且通常是不明智的。我建议你选一个。所以,如果你的项目中存在GUID,那么你就会陷入困境。看看是否可以通过顺序生成它们来将它们用作键。然后,您可以删除@Id Long id。如果没有,请将@EmbeddedId替换为@Column注释。

希望这有帮助,

祝你好运