Search code examples
javaspring-data-jdbc

Spring Data Jdbc: Name must not be empty error on nested one to many relationship implementation


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]

Solution

  • 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.