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

如何使用MapStruct映射kotlin.time.Duration与kotlinx.datetime.Instant?

data class Foo(
  val bar: String,
  // val baz: kotlin.time.Duration,
  // val baz2: kotlinx.datetime.Instant,
  val baz3: kotlinx.datetime.LocalDateTime
)

data class FooDto(
  val bar: String,
  //val baz: kotlin.time.Duration,
  // val baz2: kotlinx.datetime.Instant,
  val baz3: kotlinx.datetime.LocalDateTime
)

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
interface FooMapper {
  fun toDto(foo: Foo): FooDto
}

当前该映射器可正常处理kotlinx.datetime.LocalDateTime类型属性,但处理kotlin.time.Duration和kotlinx.datetime.Instant类型属性时失败,报错信息如下:

FooDto does not have an accessible constructor.

kotlin.time.Duration和kotlinx.datetime.Instant确实未提供公共构造方法。如何让MapStruct支持这两种类型的映射?仅需实现Instant -> Instant和Duration -> Duration的映射。


解决方法

MapStruct默认会尝试通过构造方法实例化目标类型,而Duration和Instant没有公共构造方法,且我们只需要同类型直接映射,可通过以下两种方式处理:

方式1:引入自定义转换器类

创建包含静态转换方法的工具类,明确告诉MapStruct如何处理这两种类型的映射:

object DateTimeConverters {
    fun mapDuration(source: kotlin.time.Duration): kotlin.time.Duration = source
    fun mapInstant(source: kotlinx.datetime.Instant): kotlinx.datetime.Instant = source
}

在Mapper接口中通过uses属性引入该类:

@Mapper(
    componentModel = MappingConstants.ComponentModel.SPRING,
    uses = [DateTimeConverters::class]
)
interface FooMapper {
    fun toDto(foo: Foo): FooDto
}

方式2:在Mapper中直接声明映射方法

无需额外工具类,直接在FooMapper内添加同类型映射方法,MapStruct会自动识别并使用:

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
interface FooMapper {
    fun toDto(foo: Foo): FooDto

    fun mapDuration(source: kotlin.time.Duration): kotlin.time.Duration = source
    fun mapInstant(source: kotlinx.datetime.Instant): kotlinx.datetime.Instant = source
}

两种方式核心都是让MapStruct跳过构造方法实例化逻辑,直接复用原对象完成映射。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:42:06