微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

具有多个相同类型的值对象的聚合根问题

如何解决具有多个相同类型的值对象的聚合根问题

我是 Spring Data JDBC 的新手,并使用 Spring-Boot 2.5.0、Java 11 和 Lombok(代码示例简化)创建了一个具有两个地址值的 Customer 聚合。

我有一个 Customer 实体(聚合根)和一个 Address 值对象

@Data
@Builder
@AllArgsConstructor
class Customer {
    @Id Long id;
    String name;
    Address address1;
    Address address2;
}

@Data
@Builder
@AllArgsConstructor
class Address {
    String city;
}

和 Customer 实体的一个 Repository

@Repository
public interface CustomeRepository extends CrudRepository<Customer,Long> {
}

使用 Postgres 的数据库架构看起来像这样

CREATE TABLE "customer" (
  "id"                  BIGSERIAL       NOT NULL,"name"                VARCHAR(255)    NOT NULL,PRIMARY KEY (id)
);

CREATE TABLE "address" (
  "id"                  BIGSERIAL       NOT NULL,"customer"            BIGINT,"city"                VARCHAR(255)    NOT NULL,PRIMARY KEY (id)
);

创建和存储客户

        var address1 = Address.builder().city("New York").build();
        var address2 = Address.builder().city("Chicago").build();
        var customer = Customer.builder().name("Joe").address1(address1).address2(address2).build();
        var result = customerRegistry.save(customer);

到目前为止一切顺利,数据库中的条目也很好

 id | name 
----+------
  1 | Joe


 id | customer |   city   
----+----------+----------
  1 |        1 | Chicago
  2 |        1 | New York

所以期待一位客户,但在这样做时

var customers = customerService.findAll();
customers.forEach(c -> log.debug("Customer: {}",c));

输出将是

Customer(id=1,name=Joe,address1=Address(city=New York),address2=Address(city=Chicago))
Customer(id=1,address1=Address(city=Chicago),address2=Address(city=New York))
Customer(id=1,address2=Address(city=New York))

并这样做

var customer = customerRepository.getById(result.getId());

会导致

org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1,actual 4

顺便说一句。如果客户只有一个地址字段,则一切都按预期工作。

所以我错过了什么还是这是一个错误

解决方法

您可以在一个或两个属性上添加 @Column 注释,指定不同的列以用于对 Customer 的反向引用。

例如:

class Customer {
    @Id Long id;
    String name;
    @Column("first")
    Address address1;
    @Column("second")
    Address address2;
}

需要以下 address

CREATE TABLE "address" (
  "id"                  BIGSERIAL       NOT NULL,"first"               BIGINT,"second"              BIGINT,"city"                VARCHAR(255)    NOT NULL,PRIMARY KEY (id)
);

有关超出手头具体问题的更多背景和其他替代方案,请参阅Why is a entity - value relationship implemented as a back reference in Spring Data JDBC

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。