【问题标题】:Create an entity inside an entity: how to persist在实体内部创建实体:如何持久化
【发布时间】:2012-01-15 18:52:53
【问题描述】:

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

例如,O 有一个 Order 实体,该实体具有 setCompleted() 方法。我的业务逻辑规定,无论何时完成订单,都会创建一个新的 Product 实体。请注意,OrderProduct 目前不相关(应该是吗?)。对我来说,最合乎逻辑的放置业务逻辑的地方是 setCompleted() 方法。但是我如何告诉 ORM 有一个新实体要持久化呢?实体管理器在实体内部不可用。

还是我以错误的方式解决了这个问题,我应该以其他方式实现它吗?

【问题讨论】:

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


    【解决方案1】:

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

    public void setCompleted(){
     ... 
     this.product = new Product(...);
     ...
    }
    

    然后根据您的映射(请查看您的 ORM 文档),您将不得不在订单和产品上调用实体管理器保存方法,或者只调用订单(如果关系所有者是订单并且启用了级联)。

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

    【讨论】:

    • 您能否举例说明在使用服务层时这是如何工作的?
    • 业务逻辑可以(应该)在领域对象上进行,martinfowler.com/bliki/AnemicDomainModel.html
    • 它根本没有“隐藏在模型本身中”。相反,它在域对象所在的任何地方都可用并被封装,因此不需要其他知识。
    • 我明白你的意思,这真的是一个偏好问题。 stackoverflow.com/questions/110328/… 在使用 ORM 时,我从不将业务逻辑放在域对象中,因为我希望将所有创建/删除对象/关系的代码放在同一个地方...
    • 您的链接指向 DTO 的/值对象,而不是域对象。我认为有一个普遍接受的最佳实践,那就是坚持领域对象的行为,使一切尽可能面向对象。
    【解决方案2】:

    我将创建一个新产品作为 setCompleted 方法的一部分。这样每次 Product 被持久化时,任何映射的实体也会被持久化。只需让 hibernate 完成这项工作......不要自己使用服务层显式持久化它。

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

    @OneToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name="product_fk",nullable = false) 
    private Product product;
    
    public void setCompleted(){
     setProduct(new Product(...));
    }
    

    DDD with hibernate

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 您也想使用工厂来创建新实体 (ProductFactory),工厂可以注入 OrderService 并在调用 setComplete() 时完成工作。这样也很容易模拟和单元测试。
      猜你喜欢
      • 2021-05-06
      • 2019-10-20
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      相关资源
      最近更新 更多