spring-data-jdbc: объект запроса, содержащий отношение 1-n с JOOQ

Я пытаюсь загрузить объекты, содержащие ссылку на другой объект (1-n) с помощью JOOQ (на основе spring-data-jdbc).

Я начал расширять spring- data-jdbc-jooq-example.

Скорректированная модель с отношением 1-n:

@Data
public class Category {

    private @Id Long id;
    private String name, description;
    private AgeGroup ageGroup;
    private Set<SubCategory> subCategories;

    public Category() {}

    public Category(Long id, String name, String description, AgeGroup ageGroup) {
        this(id, name, description, ageGroup, new HashSet<>());
    }

    public Category(Long id, String name, String description, AgeGroup ageGroup, Set<SubCategory> subCategories) {
        this.id = id;
        this.name = name;
        this.description = description;
        this.ageGroup = ageGroup;
        this.subCategories = subCategories;
    }
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SubCategory {

    private @Id Long id;
    private String title;

}

Я написал два запроса: один с помощью @Query-аннотации в CrudRepository и один с помощью JOOQ в JooqRepository.

interface CategoryRepository extends CrudRepository<Category, Long>, JooqRepository {

    @Query("SELECT * FROM category")
    List<Category> findAllWithQuery();

}
public interface JooqRepository {

    List<Category> findAllWithJooq();
}
public class JooqRepositoryImpl implements JooqRepository {

    private final DSLContext dslContext;

    public JooqRepositoryImpl(DSLContext dslContext) {
        this.dslContext = dslContext;
    }

    @Override
    public List<Category> findAllWithJooq() {
        return dslContext.select()
                .from(CATEGORY)
                .fetchInto(Category.class);
    }
}

(для меня оба метода должны возвращать один и тот же набор результатов, потому что они выполняют один и тот же запрос ?!)

Но мой модульный тест не работает:

@Test
public void exerciseRepositoryForSimpleEntity() {
  // create some categories
  SubCategory sub0 = new SubCategory(null, "sub0");
  SubCategory sub1 = new SubCategory(null, "sub1");
  Category cars = new Category(null, "Cars", "Anything that has approximately 4 wheels", AgeGroup._3to8, Sets.newLinkedHashSet(sub0, sub1));

  // save category
  repository.saveAll(asList(cars));

  // execute
  List<Category> actual = repository.findAllWithJooq();
  List<Category> compare = repository.findAllWithQuery();
  Output.list(actual, "JOOQ");
  Output.list(compare, "Query");

  // verify
  assertThat(actual).as("same size of categories").hasSize(compare.size());
  assertThat(actual.get(0).getSubCategories()).as("same size of sub-categories").hasSize(compare.get(0).getSubCategories().size());
}

с участием

java.lang.AssertionError: [same size of sub-categories] 
Expecting actual not to be null

Как видно из следующего вывода, подкатегории, запрошенные JOOQ, не будут загружены:

2019-11-26 16:28:00.749  INFO 18882 --- [           main] example.springdata.jdbc.jooq.Output      : ==== JOOQ ====
Category(id=1,
    name=Cars,
    description=Anything that has approximately 4 wheels,
    ageGroup=_3to8,
    subCategories=null)
2019-11-26 16:28:00.749  INFO 18882 --- [           main] example.springdata.jdbc.jooq.Output      : ==== Query ====
Category(id=1,
    name=Cars,
    description=Anything that has approximately 4 wheels,
    ageGroup=_3to8,
    subCategories=[SubCategory(id=1,
    title=sub0),
    SubCategory(id=2,
    title=sub1)])

Это используемая схема базы данных:

CREATE TABLE IF NOT EXISTS category (
  id INTEGER IDENTITY PRIMARY KEY,
  name VARCHAR(100),
  description VARCHAR(2000),
  age_group VARCHAR(20)
);

CREATE TABLE IF NOT EXISTS sub_category (
    id INTEGER IDENTITY PRIMARY KEY,
    title VARCHAR(100),
    category INTEGER
)

person einsA    schedule 26.11.2019    source источник


Ответы (1)


В варианте JOOQ JOOQ выполняет преобразование из ResultSet в экземпляры объекта. Поскольку JOOQ не знает об интерпретации агрегатов, как это делает Spring Data JDBC, он гидратирует только сам Category, а не содержащийся Set из SubCategory.

Spring Data JDBC, с другой стороны, интерпретирует структуру Category и на основе этого выполняет другой оператор для загрузки подкатегорий.

person Jens Schauder    schedule 27.11.2019