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).
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;
}
and one Repository for the Customer entity
@Repository
public interface CustomeRepository extends CrudRepository<Customer, Long> {
}
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)
);
Creating and storing a Customer
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));
the output will be
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))
and doing this
var customer = customerRepository.getById(result.getId());
will result in
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?