jooq, simpleflatmapper, kotlin 映射
Posted
技术标签:
【中文标题】jooq, simpleflatmapper, kotlin 映射【英文标题】:jooq, simpleflatmapper, kotlin mapping 【发布时间】:2021-12-26 18:57:17 【问题描述】:我正在将一个 java 项目转换为 kotlin,但在使用查询结果构造数据对象时出错。查询是 Docs 和 Questions 之间具有一对多关系的联接。这在 java 中有效,但我无法让它与 kotlin 一起使用。我尝试过提供默认值并使用无参数项目。不确定这是 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)
【问题讨论】:
我不确定,但如果您添加 @NoArgsConstructor,您还需要将 @AllArgsConstructor 添加到 Doc 类中。 这是使用 kotlin-noarg 项目创建的自定义注解。它似乎不适用于这个问题。这不是龙目岛注释。 我只是认为可能是 NoArgs 注释阻止了 jooq 能够创建 Doc 类的实例所需的隐式构造函数。 【参考方案1】:我无法评论您的 SimpleFlatMapper 用法,但从 jOOQ 3.15 开始,如果您的底层 SQL 数据库产品以某种方式支持 SQL/JSON or SQL/XML,则有更好的嵌套集合方法:使用 new MULTISET
(or MULTISET_AGG
) operator!
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))
这是所有类型安全且无反射的。
【讨论】:
以上是关于jooq, simpleflatmapper, kotlin 映射的主要内容,如果未能解决你的问题,请参考以下文章
JOOQ + Gradle:如何为 JOOQ 生成器定义多个模式?