I'm using Spring Boot 2.2.0.RELEASE
and spring-data-jdbc 1.1.0.RELEASE
Tried to implement nested one to many relationship using spring-data-jdbc.
One book has many chapters and each chapter has many parts.
public class Book {
private Set<Chapter> chapters = new HashSet<>();
public Set<Chapter> getChapters(){
return chapters;
}
}
public class Chapter{
public Set<Part> getParts() {
return parts;
}
private Set<Part> parts = new HashSet<>();
}
public class Part { }
public interface BookCrudRepository extends CrudRepository<Book, Long> {
public Set<Book> findAll();
}
@Autowired
BookRepository bookRepository;
@GetMapping("/book")
public Set<Book> getBookList() {
return bookCrudRepository.findAll();
}
CREATE TABLE IF NOT EXISTS book (
id SERIAL PRIMARY KEY,
);
CREATE TABLE IF NOT EXISTS chapter (
id SERIAL PRIMARY KEY,
book_id int references book(id),
);
CREATE TABLE IF NOT EXISTS part (
chapter_id int references chapter(id),
);
Without Part, findAll returns all Books with Chapters. With Part, I received this runtime error:
java.lang.IllegalArgumentException: Name must not be empty!
at org.springframework.util.Assert.hasText(Assert.java:284) ~[spring-core-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.data.relational.domain.Identifier.withPart(Identifier.java:116) ~[spring-data-relational-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.resolveRelation(BasicJdbcConverter.java:349) ~[spring-data-jdbc-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.readOrLoadProperty(BasicJdbcConverter.java:333) ~[spring-data-jdbc-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.populateProperties(BasicJdbcConverter.java:322) ~[spring-data-jdbc-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.createInstanceInternal(BasicJdbcConverter.java:458) ~[spring-data-jdbc-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.mapRow(BasicJdbcConverter.java:307) ~[spring-data-jdbc-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.data.jdbc.core.convert.BasicJdbcConverter.mapRow(BasicJdbcConverter.java:252) ~[spring-data-jdbc-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.data.jdbc.core.convert.EntityRowMapper.mapRow(EntityRowMapper.java:68) ~[spring-data-jdbc-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:94) ~[spring-jdbc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
According to the source you posted none of your entities has an id, although the schema shows Book
and Chapter
probably have one.
Page
needs one as well if it is supposed to be stored in a Set
.
Basically the aggregate root (Book
) and all entities stored in a Set
need an id.
Entities referenced directly or via a List
or a Map
don't need an id since the get the id from the referencing entity plus the list index or map key.