2014-02-08 37 views
3

我對DDD相當陌生。我見過許多使用通用AggregateId(帶有包含GUID的String)作爲聚合根鍵的示例項目。DDD彙總ID和外鍵

我想知道如何從一個OneToMany關係中引用一個孩子的aggregateRoot。

假設有一個Order AggregateRoot和一個OrderLine。在GUID旁邊有一個額外的生成(例如序列)ID是否明智,因此OrderLine可以引用數據庫級別的ID?或者是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; 
+0

他們所說的AggregateRoot,它的身份是不是SQL主鍵!這取決於你如何堅持你的聚合,聚合根可以有其他聚合的參考。 – Ehsan

回答

1

首先,我想澄清的是DDD是所有關於域建模和無關與域是如何堅持。它可能會被保存在一個數據庫中,但它也可能在一個文本文件中。從領域建模的角度來看,重要的是哪些(以及如何)實體與其他實體相關聯,但通常不是關係數據庫中它們如何相關。就機智問一位銷售代表。訂單項如何識別訂單的一部分,他會問你什麼是你的錯。

性能方面,使用GUID作爲密鑰存在一些風險。隨機生成的GUID不適用於聚簇索引。最好使用順序生成算法,並讓數據庫爲您提供這些GUID。下面是一個討論的鏈接這個話題:

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

我會建議你閱讀特別this answer。我同意Dan的觀點,即有順序的GUID是沒有意義的。

從關係上看,我覺得在同一條記錄中有兩個標識符似乎是不必要的也是不明智的。我會建議你選一個。所以,如果不知何故,你在項目中堅持使用GUID。通過順序生成它們來查看是否可以將它們用作鍵。然後你可以刪除你的@Id Long id。如果不是,則用@Column註釋替換@EmbeddedId

希望這有助於

好運

+0

Vernon在實施DDD時將此稱爲代理ID,並將其描述爲處理RDBMS/ORM要求和限制的完美有效方法。 –

+0

謝謝,但我知道。像Long ID這樣的GUID雖然不是域模型標識,這也是一種替代身份,因此我的建議。 –