在实体内创建实体:如何持久化

时间:2011-12-08 10:09:05

标签: hibernate nhibernate orm domain-driven-design doctrine-orm

使用对象关系映射器时,如何在另一个实体中创建新实体以及如何保留它们?我使用的是Doctrine 2(PHP),但我认为这同样适用于Hibernate(Java)和NHibernate(C#)。

例如,O有一个Order实体,其setCompleted()方法。我的业务逻辑规定,无论何时完成订单,都会创建一个新的Product实体。请注意,OrderProduct目前无关(它们应该是?)。对我而言,将业务逻辑置于setCompleted()方法中的最合理的位置。但是,我如何告诉ORM有一个新的实体要坚持?实体经理在实体内部不可用。

或者我是以错误的方式处理这个问题,我应该以其他方式实现吗?

3 个答案:

答案 0 :(得分:1)

您的Order类需要具有对Product的引用,该引用可以为null。当您调用setCompleted时,您可以创建一个新的Product实例并进行分配。像

这样的东西
public void setCompleted(){
 ... 
 this.product = new Product(...);
 ...
}

然后根据您的映射(检查您的ORM文档),您必须在订单和产品上调用entiity manager保存方法,或者只是订购(如果关系所有者是订单并启用了级联)。

由于这是业务逻辑,我不会将其隐藏在模型本身中,而是隐藏在服务层中。

答案 1 :(得分:1)

我会在setCompleted方法中创建一个新产品。因此,每次产品持久化时,任何映射的实体也会被持久化。让hibernate做腿部工作......不要使用服务层明确地保持它自己。

例如在Order中(假设产品被正确地声明为实体):

@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="product_fk",nullable = false) 
private Product product;

public void setCompleted(){
 setProduct(new Product(...));
}

DDD with hibernate

答案 2 :(得分:1)

您应该从服务层创建新产品。 例如。您可以拥有一个OrderService,它可以引入(与之对话)您的订单存储库和产品存储库。当您调用SetCompleted()时,您还可以创建产品(通过Product Repository)。

您还可以查看Pipes and Filters pattern并创建订单管道。这样你就可以插入一个接一个地执行的各种步骤(过滤器)。

您不应该在Order实体中创建产品,因为您的域实体应该与数据库无关。您需要一个存储库来创建新产品,因此服务层通过与数据访问层进行通信来促进这一点。