使用对象关系映射器时,如何在另一个实体中创建新实体以及如何保留它们?我使用的是Doctrine 2(PHP),但我认为这同样适用于Hibernate(Java)和NHibernate(C#)。
例如,O有一个Order
实体,其setCompleted()
方法。我的业务逻辑规定,无论何时完成订单,都会创建一个新的Product
实体。请注意,Order
和Product
目前无关(它们应该是?)。对我而言,将业务逻辑置于setCompleted()
方法中的最合理的位置。但是,我如何告诉ORM有一个新的实体要坚持?实体经理在实体内部不可用。
或者我是以错误的方式处理这个问题,我应该以其他方式实现吗?
答案 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(...));
}
答案 2 :(得分:1)
您应该从服务层创建新产品。 例如。您可以拥有一个OrderService,它可以引入(与之对话)您的订单存储库和产品存储库。当您调用SetCompleted()时,您还可以创建产品(通过Product Repository)。
您还可以查看Pipes and Filters pattern并创建订单管道。这样你就可以插入一个接一个地执行的各种步骤(过滤器)。
您不应该在Order实体中创建产品,因为您的域实体应该与数据库无关。您需要一个存储库来创建新产品,因此服务层通过与数据访问层进行通信来促进这一点。