如何在 DDD 中实现 Vaughn Vernon 关于聚合中引用的建议
How to implement Vaughn Vernon's recommendation in DDD about references in aggregates
遵循 DDD 中有关聚合引用的 Vaughn Vernon 建议
Let aggregates reference other aggregates by ID (identity), not the aggregate itself.
如何使用 JPA 和 Hibernate 4.3 完成此操作。11.Final?
我尝试使用 this example:
类似
@Entity
public class OrdenItem implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(targetEntity = Orden.class, optional = false)
private Long ordenId;
@ManyToOne(targetEntity = Product.class, optional = false)
private Long productId;
.
.
.
但是当我尝试使用 Spring 数据
检索一些实例时
@Query(""
+ " SELECT b "
+ " FROM OrdenItem b "
)
List<OrdenItem> findByYYYY();
出现如下错误
java.lang.IllegalArgumentException: Can not set java.lang.Long field com.aggregates.model.OrdenItem.ordenId to com.aggregates.model.Orden
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:1.8.0_51]
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:1.8.0_51]
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) ~[na:1.8.0_51]
我知道如果我将代码更改为
,这会起作用
@ManyToOne
private Orden orden;
@ManyToOne
private Product product;
但我想听从 Vaughn Vernon 的建议
刚搭上
@ManyToOne(targetEntity = Product.class, optional = false)
并将 orderId 和 productId 作为数字保存在 table。
@Column(name="PRODUCT_ID")
就是这样。
如果您想获取订单及其商品,然后获取字符串表示形式,您将需要产品名称,我认为您希望在此处检索每个订单商品的产品。
请允许我说这就是 Vaughn 会做的事情:
首先,我根本不需要通过标识符 orderId 保存从 OrderItem 到 Order 的引用,这样您就可以安全地删除它。从域服务中,您要做的只是检索订单聚合根及其聚合的项目集合。我不会让每个项目都包含一个 productId,而是将其更改为使每个 orderItem 都包含我的产品的另一个概念标识,它必须是产品 SKU 或其他东西,你也可以保留它的名称,就像它是一个订单一样现实世界。无论如何,这些值根本没有改变,是 immutable.
塞巴斯蒂安。
遵循 DDD 中有关聚合引用的 Vaughn Vernon 建议
Let aggregates reference other aggregates by ID (identity), not the aggregate itself.
如何使用 JPA 和 Hibernate 4.3 完成此操作。11.Final?
我尝试使用 this example:
类似
@Entity
public class OrdenItem implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(targetEntity = Orden.class, optional = false)
private Long ordenId;
@ManyToOne(targetEntity = Product.class, optional = false)
private Long productId;
.
.
.
但是当我尝试使用 Spring 数据
检索一些实例时@Query(""
+ " SELECT b "
+ " FROM OrdenItem b "
)
List<OrdenItem> findByYYYY();
出现如下错误
java.lang.IllegalArgumentException: Can not set java.lang.Long field com.aggregates.model.OrdenItem.ordenId to com.aggregates.model.Orden at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:1.8.0_51] at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:1.8.0_51] at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) ~[na:1.8.0_51]
我知道如果我将代码更改为
,这会起作用@ManyToOne
private Orden orden;
@ManyToOne
private Product product;
但我想听从 Vaughn Vernon 的建议
刚搭上
@ManyToOne(targetEntity = Product.class, optional = false)
并将 orderId 和 productId 作为数字保存在 table。
@Column(name="PRODUCT_ID")
就是这样。
如果您想获取订单及其商品,然后获取字符串表示形式,您将需要产品名称,我认为您希望在此处检索每个订单商品的产品。 请允许我说这就是 Vaughn 会做的事情: 首先,我根本不需要通过标识符 orderId 保存从 OrderItem 到 Order 的引用,这样您就可以安全地删除它。从域服务中,您要做的只是检索订单聚合根及其聚合的项目集合。我不会让每个项目都包含一个 productId,而是将其更改为使每个 orderItem 都包含我的产品的另一个概念标识,它必须是产品 SKU 或其他东西,你也可以保留它的名称,就像它是一个订单一样现实世界。无论如何,这些值根本没有改变,是 immutable.
塞巴斯蒂安。