Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 值对象、实体和字典类型的DDD建模_Java_Hibernate_Jpa_Domain Driven Design - Fatal编程技术网

Java 值对象、实体和字典类型的DDD建模

Java 值对象、实体和字典类型的DDD建模,java,hibernate,jpa,domain-driven-design,Java,Hibernate,Jpa,Domain Driven Design,我想把我的问题带给更多的听众,因为我们已经在公司讨论了一段时间,但找不到答案 假设我们有事务对象,它是聚合根。 在交易中我们有钱,这是价值对象 class Transaction { private Money money; // other stuff } 及 这样的事务可以持久化(我们使用hibernate)到db到简单的表事务中 一切都会很好但是。。。客户要求我们在数据库中有货币表(我们称之为字典表),每个有钱的表(包括交易)都需要指向货币表: +------------

我想把我的问题带给更多的听众,因为我们已经在公司讨论了一段时间,但找不到答案

假设我们有事务对象,它是聚合根。 在交易中我们有,这是价值对象

class Transaction {
    private Money money;
    // other stuff
}

这样的事务可以持久化(我们使用hibernate)到db到简单的表事务中

一切都会很好但是。。。客户要求我们在数据库中有货币表(我们称之为字典表),每个有钱的表(包括交易)都需要指向货币表:

+-----------------+           +-----------------+
| transaction     |           |curency          |
+-----------------+           +-----------------+
|id : bigint      |     +---> | id: bigint      |
|amount: decimal  |     |     | code: varchar   |
|curr_id: bigint  | ----+     | name: varchar   |
|other...         |           +-----------------+
+-----------------+
所以从现在开始,Money对象应该是这样的:

class Money {
    private BigDecimal amount;
    private Currency currency;
}

从现在起,我们不能称之为值对象:(或者我们可以吗?这也使我们持久化对象的方式变得复杂,因为我们需要编写自己的自定义类型,因此不能再使用hibernate Embeddeble了。当然,我们不是第一个遇到这种问题的人,因为字典类型在使用中很流行,问题是,如何在ddd建模的范围内处理它们

在处理地址时,我们将面临类似的问题。因此,我们知道我们有像Country和FederalState这样的字典(它们是分层的)。我们还知道我们应用程序中的许多对象(例如Institute)有自己的地址,但也与FederalState有联系。因此,在simpe情况下,我们将有:

class Institution {
    Address address;
    // ...
}
在哪里

但我们需要它与fedral state表有关系,因此地址如下所示:

class Address {
    String street;
    String houseNo;
    // etc..
    FederalState federalState;
}
所以我们再次面临同样的问题,地址从此不再是价值对象。 我们知道如何在技术上做到这一点,但从od ddd的角度看,什么是正确的方法?

“从od ddd的角度看,什么是正确的方法?”

首先,使用字典实体并没有错。可能只是因为与字符串值不同,使用字典实体的关系:

  • 避免拼写错误(更健壮)
  • 允许在不修改代码的情况下管理“值”集-您只需从存储中加载字典并填充下拉列表,而不是在代码中定义枚举(更灵活)

  • 撇开上述两种情况不谈,业务需求可能会强加这种设计。例如,对于
    货币
    情况:当表示为一个实体时,允许定义
    汇率
    关系,其本身可能受制于一种存储汇率随时间变化的方法。
    具有
    状态
    DICT对于(可能的未来)扩展处理不同的销售税政策或立法限制(产品/服务在某些州是不允许的,请参见“药用”杂草等等)来说,这是一个很好的基础。

    “从现在起,我们不能称之为价值对象:(”-为什么?@guillaume31因为,现在它有了自己的表,它获得了更高的地位,它可能会觉得被冒犯?在你的问题中,我看不到一个钱表。此外,判断一个对象是否是值对象与数据库表几乎没有什么关系。@guillaume31不仅是“任何时刻的性质”,而且还与“需要跟踪进化”——如果其属性的变化足够重要,可以在其进化过程中跟踪,那么我们所说的肯定是“实体”而不是“价值”"。您的模型中很可能有一个值对象,从持久性世界的角度来看,它是一个实体,这很好,只要它在模型中保持一个值。并非所有的值对象都必须是可嵌入的,否则您永远无法在关系数据库中有效地建模一组值。现在,在您的Currency-FederalState示例中,只要货币只引用州的ID,您就可以了。
    class Institution {
        Address address;
        // ...
    }
    
    class Address {
        String street;
        String houseNo;
        // etc..
        String federalState;
        String country;
    }
    
    class Address {
        String street;
        String houseNo;
        // etc..
        FederalState federalState;
    }