You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin搭配Exposed ORM和KGraphql初始化Schema报泛型不支持错误

问题原因

你遇到的报错是因为Exposed ORM的实体类(继承IntEntity)自带多个ORM内部使用的非业务属性,其中包含泛型类型kotlin.collections.Map<org.jetbrains.exposed.sql.Expression<*>, kotlin.Int>。KGraphQL默认会扫描注册类的所有属性,而GraphQL规范不支持泛型Map类型,因此触发异常。

解决方案

方案1:显式指定GraphQL类型暴露的属性

修改Schema定义代码,在注册ExposedFeed和ExposedEntry类型时,仅声明你需要对外暴露的业务字段,排除Exposed内部属性即可:

fun SchemaBuilder.RSSFeedschema() {
    query("RSSFeeds") {
        resolver { -> 
            transaction {
                ExposedFeed.all()
            }
        }
    }
    type<ExposedFeed> {
        // 仅显式注册需要暴露的业务字段
        property("id") { it.id.value }
        property(ExposedFeed::description)
        property(ExposedFeed::docs)
        property(ExposedFeed::feedType)
        property(ExposedFeed::link)
        property(ExposedFeed::author)
        property(ExposedFeed::authors)
        property(ExposedFeed::categories)
        property(ExposedFeed::language)
        property(ExposedFeed::title)
        property(ExposedFeed::uri)
        property(ExposedFeed::webMaster)
        property(ExposedFeed::timestamp)
    }
    type<ExposedEntry> {
        property("id") { it.id.value }
        property(ExposedEntry::title)
        property(ExposedEntry::author)
        property(ExposedEntry::description)
        property(ExposedEntry::categories)
        property(ExposedEntry::contents)
        property(ExposedEntry::comments)
        property(ExposedEntry::uri)
        property(ExposedEntry::publishedDate)
        property(ExposedEntry::updatedDate)
        // 如果需要关联返回Feed信息也可以加上
        property("feed") { it.exposedFeed }
    }
}

方案2:新增DTO层做数据转换(更推荐)

不要直接把Exposed ORM实体暴露给GraphQL层,定义普通Kotlin数据类作为传输对象,返回前做一层转换,从根源上避免ORM内部属性泄露:

  1. 定义DTO类和转换方法
// Feed DTO
data class RSSFeedDTO(
    val id: Int,
    val description: String,
    val docs: String?,
    val feedType: String?,
    val link: String?,
    val author: String?,
    val authors: String?,
    val categories: String?,
    val language: String?,
    val title: String?,
    val uri: String?,
    val webMaster: String?,
    val timestamp: String?
)

// Entry DTO
data class RSSEntryDTO(
    val id: Int,
    val title: String,
    val author: String?,
    val description: String?,
    val categories: String?,
    val contents: String?,
    val comments: String?,
    val uri: String?,
    val publishedDate: String?,
    val updatedDate: String?
)

// 扩展方法实现实体转DTO
fun ExposedFeed.toDTO() = RSSFeedDTO(
    id = id.value,
    description = description,
    docs = docs,
    feedType = feedType,
    link = link,
    author = author,
    authors = authors,
    categories = categories,
    language = language,
    title = title,
    uri = uri,
    webMaster = webMaster,
    timestamp = timestamp
)
  1. 修改Schema定义和resolver
fun SchemaBuilder.RSSFeedschema() {
    query("RSSFeeds") {
        resolver { -> 
            transaction {
                ExposedFeed.all().map { it.toDTO() }
            }
        }
    }
    // 直接注册DTO类型,不会有多余内部属性
    type<RSSFeedDTO>()
    type<RSSEntryDTO>()
}

内容的提问来源于stack exchange,提问作者SomethingsGottaGive

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 13:33:03