jOOQ convertFrom mapping does not find constructor

Viewed 48

I'm trying to use the jOOQ ad-hoc converter to map results into Java classes, as documented here: https://www.jooq.org/doc/latest/manual/sql-execution/fetching/ad-hoc-converter/

However, I receive the error "cannot resolve constructor 'MyClassName'" when trying to convert a record into my class.

When I let IntelliJ auto-create a constructor for me, it generates a constructor where all parameters are Object, as opposed to the actual types returned. This is odd, because the type suggestions for each other step of my query indicate that the IDE does know the correct types of each field of the returned records.

The only difference between my code and the documentation is that the documentation mentions using records that are implemented, whereas my classes are auto-generated from SQL by jOOQ.

My code fails on the point indicated below:

List<Author> result = create.select(
          AUTHOR.FIRST_NAME,
          AUTHOR.LAST_NAME,
          
          // This is now a Field<List<Book>>
          multiset(
              selectDistinct(
                  BOOK.language().CD,
                  BOOK.language().DESCRIPTION)
              .from(BOOK)
              .where(BOOK.AUTHOR_ID.eq(AUTHOR.ID))

                             //  "Cannot resolve constructor 'Book' vvvvv
          ).as("books").convertFrom(r -> r.map(Records.mapping(Book::new))),

          // This is now a Field<List<BookStore>>
          multiset(
              selectDistinct(BOOK_TO_BOOK_STORE.BOOK_STORE_NAME)
              .from(BOOK_TO_BOOK_STORE)
              .where(BOOK_TO_BOOK_STORE.tBook().AUTHOR_ID.eq(AUTHOR.ID))
          ).as("book_stores").convertFrom(r -> r.map(Records.mapping(BookStore::new))))
      .from(AUTHOR)
      .orderBy(AUTHOR.ID)
      .fetch(Records.mapping(Author::new));

I'm using the example code from the manual here for simplicity, but my query is essentially the same but with my own classes:

final var items =
    conf.dsl()
        .select(
            RUN.fieldsRow().as("run").convertFrom(r -> r.into(RunRecord.class)),
            RUN_PROGRESS
                .fieldsRow()
                .as("run_progress")
                .convertFrom(r -> r.into(RunProgressRecord.class)),
            multiset(
                    select(REASON.fieldsRow())
                        .from(REASON)
                        .where(REASON.RUN_ID.eq(RUN.ID)))
                .as("reasons")

              //  "Cannot resolve constructor 'ReasonRecord' vvvvv
                .convertFrom(r -> r.map(mapping(ReasonRecord::new))))
        .from(RUN)
        .leftOuterJoin(RUN_PROGRESS)
        .on(RUN_PROGRESS.RUN_ID.eq(RUN.ID))
        .fetch();

Resolving the classes using reflection does work, but at the expense of type-safety.

0 Answers
Related