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

如何在MapStruct中设置Instant字段为当前时间now()?

问题:MapStruct设置Instant类型createdAt字段为当前时间失败

我的POJO类中有一个Instant类型的createdAt字段,希望创建记录时自动设为当前时间(now()),用MapStruct实现时配置出错。

Mapper代码

@Mapper(componentModel = "spring", imports = {Instant.class})
public interface CreatePostRequestMapper {

    // @Mapping(target = "createdAt", defaultExpression ="java(Instant.now())")
    @Mapping(target = "createdAt", defaultValue = "java(Instant.now())")
    Post toEntity(CreatePostRequest source);

    CreatePostRequest toDto(Post destination);
}

Post和CreatePostRequest类均包含同名的私有Instant createdAt属性。

服务方法代码

private final CreatePostRequestMapper createPostRequestMapper;

public PostDetails createPost(@Valid CreatePostRequest request) {
    final Post post = createPostRequestMapper.toEntity(request);

    // 代码省略
}

运行时错误

Request processing failed; nested exception is java.time.format.DateTimeParseException: Text 'java(Instant.now())' could not be parsed at index 0] with root cause


解决方法

问题根源

你混淆了MapStruct的两个注解属性:defaultValue是用来设置字符串常量默认值的,MapStruct会把你写的"java(Instant.now())"当作普通字符串去转成Instant类型,自然触发日期解析错误。而要执行Java代码表达式,得用defaultExpression属性。

正确配置

把注解改成defaultExpression即可:

@Mapper(componentModel = "spring", imports = {Instant.class})
public interface CreatePostRequestMapper {

    @Mapping(target = "createdAt", defaultExpression = "java(Instant.now())")
    Post toEntity(CreatePostRequest source);

    CreatePostRequest toDto(Post destination);
}

额外说明

  • defaultExpression接收合法的Java代码片段,MapStruct会直接把这段代码生成到映射方法里
  • 因为已经在@Mapper的imports中引入了Instant,所以表达式里不用写全限定类名java.time.Instant.now()
  • 如果你的业务场景中,CreatePostRequest的createdAt可能存在非null值,需要覆盖的话,可以用expression属性,但创建记录的场景下,defaultExpression更合适——只有当源对象的createdAt为null时,才会执行表达式设置当前时间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:22:28