1

我正在将一个 java 项目转换为 kotlin,但在使用查询结果构造数据对象时出错。查询是在 Docs 和 Questions 之间具有一对多关系的联接。这适用于java,但我无法让它与kotlin一起使用。我尝试过提供默认值并使用 no-args 项目。不确定这是 kotlin、jooq 还是简单的平面映射器问题。

Spring boot: 2.5.4
kotlin: 1.5.31

implementation 'org.simpleflatmapper:sfm-jooq:8.2.3'
implementation 'org.springframework.boot:spring-boot-starter-jooq'



@Repository
open class DocRepository(private val dslContext: DSLContext) {
    companion object : KLogging()

    private val docMapper = SelectQueryMapperFactory.newInstance().newMapper(
        Doc::class.java
    )

override fun getDocDetails(docId: Int): Doc {
        return docMapper.asList(
            dslContext.select(
                Tables.DOC.DOC_ID,
                Tables.DOC.TITLE,
                Tables.DOC.DESCRIPTION,
                Tables.DOC.QUESTION.QUESTION_ID,
                Tables.DOC.QUESTION.DOC_ID,
                Tables.DOC.QUESTION.QUESTION,
                Tables.DOC.QUESTION.ANSWER
            )
                .from(Tables.DOC).leftJoin(Tables.QUESTION)
                .on(Tables.QUESTION.DOC_ID.eq(Tables.DOC.DOC_ID))
                .where(Tables.DOC.DOC_ID.eq(docId))
        ).stream().findFirst().get()
    }

}




data class Doc(
    var docId: Int? = null,
    val title: String? = "",
    val description: String? = "",
    var questions: List<Question?>? = null,
)


data class Question(
    var questionId: Int? = null,
    var docId: Int? = null,
    var question: String? = "",
    var answer: String? = ""
)



org.jooq.exception.MappingException: No constructor available for class com.test.entity.Doc
at org.simpleflatmapper.jooq.SelectQueryMapper.getMapper(SelectQueryMapper.java:186)
at org.simpleflatmapper.jooq.SelectQueryMapper.asList(SelectQueryMapper.java:46)
4

1 回答 1

0

我无法评论您的 SimpleFlatMapper 用法,但从 jOOQ 3.15 开始,如果您的底层 SQL 数据库产品以某种方式支持SQL/JSON 或 SQL/XML ,则有一种更好的嵌套集合方法:使用MULTISET(或MULTISET_AGG)运算符

override fun getDocDetails(docId: Int): Doc {
    return dslContext.select(
            DOC.DOC_ID,
            DOC.TITLE,
            DOC.DESCRIPTION,
            multiset(
                select(
                    QUESTION.QUESTION_ID,
                    QUESTION.DOC_ID,
                    QUESTION.QUESTION,
                    QUESTION.ANSWER
                )
                .from(QUESTION)
                .where(QUESTION.DOC_ID.eq(DOC.DOC_ID))
            ).convertFrom { it.map(Records.mapping(::Question)) }
        )
        .from(DOC)
        .where(DOC.DOC_ID.eq(docId))
        .fetchSingle(Records.mapping(::Doc))
    }
}

这是所有类型安全且无反射的。

于 2021-11-16T15:38:59.560 回答