问题描述
我是 Spring Data JDBC 的新手,并使用 Spring-Boot 2.5.0、Java 11 和 Lombok(代码示例简化)创建了一个具有两个地址值的 Customer 聚合.
I'm new to Spring Data JDBC and create a Customer aggregate with two Address values using Spring-Boot 2.5.0, Java 11 and Lombok (code examples simplified).
我有一个 Customer 实体(聚合根)和一个 Address 值对象
I have one Customer entity (aggregate root) and one Address value object
@Data
@Builder
@AllArgsConstructor
class Customer {
@Id Long id;
String name;
Address address1;
Address address2;
}
@Data
@Builder
@AllArgsConstructor
class Address {
String city;
}
和 Customer 实体的一个 Repository
and one Repository for the Customer entity
@Repository
public interface CustomeRepository extends CrudRepository<Customer, Long> {
}
使用 Postgres 的数据库架构看起来像这样
Using Postgres the db schema looks like this
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);
到目前为止一切顺利,数据库中的条目也很好
So far so good, also the entries in the database looking fine
id | name
----+------
1 | Joe
id | customer | city
----+----------+----------
1 | 1 | Chicago
2 | 1 | New York
所以期待一位客户,但在这样做时
So expecting one Customer, but when doing this
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, name=Joe, address1=Address(city=Chicago), address2=Address(city=Chicago))
Customer(id=1, name=Joe, address1=Address(city=New York), address2=Address(city=New York))
Customer(id=1, name=Joe, address1=Address(city=Chicago), address2=Address(city=New York))
并这样做
var customer = customerRepository.getById(result.getId());
将导致
org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 4
顺便说一句.如果客户只有一个地址字段,则一切都按预期工作.
Btw. If the Customer has only one address field everything works as expected.
所以我错过了什么还是这是一个错误?
So do I miss something or is this a bug?
推荐答案
您可以在一个或两个属性上添加 @Column
批注,指定不同的列以用于对 客户
.
You can put a @Column
annotation on one or both attributes, specifying different columns to use for the back-reference to 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)
);
有关超出手头特定问题的更多背景和其他替代方案,请参阅为什么实体 - 值关系实现为Spring Data JDBC 中的反向引用
For more background and other alternatives that go beyond the specific problem at hand see Why is a entity - value relationship implemented as a back reference in Spring Data JDBC
这篇关于具有多个相同类型的值对象的聚合根问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!