Micronaut(Kotlin)中忽略自动生成ID转换请求DTO至@MappedEntity
解决Micronaut Kotlin中@MappedEntity自动生成主键的DTO转换问题
针对你遇到的主键字段必填导致转换函数编译失败的问题,这里提供几种实用的原生解决方案,无需额外引入依赖:
方法1:将主键字段设为可空并赋予默认值
这是最简洁的方案,因为@GeneratedValue标记的主键由数据库自动生成,插入时无需我们提供值。在Kotlin数据类中把purchaseId设为可空类型并赋予默认值null,创建实体时就可以跳过该字段:
import io.micronaut.data.annotation.GeneratedValue import io.micronaut.data.annotation.Id import io.micronaut.data.annotation.MappedEntity @MappedEntity data class PurchasedDataEntity( @Id @GeneratedValue(GeneratedValue.Type.IDENTITY) val purchaseId: Long? = null, // 可空类型+默认值null val productName: String, val quantity: Int // 其他业务字段 )
转换函数可以直接忽略主键字段:
fun PurchaseRequestDto.toPurchasedDataEntity(): PurchasedDataEntity { return PurchasedDataEntity( productName = this.productName, quantity = this.quantity // 无需传递purchaseId,自动使用默认值null ) }
调用repository.save()时,Micronaut Data会自动识别该字段为数据库生成,不会将null插入数据库,而是由PostgreSQL生成主键值。
方法2:添加次级构造函数
如果不想修改主键字段的可空性,可以给实体类添加一个不带主键参数的次级构造函数,用临时值占位(插入时会被数据库覆盖):
@MappedEntity data class PurchasedDataEntity( @Id @GeneratedValue(GeneratedValue.Type.IDENTITY) val purchaseId: Long, val productName: String, val quantity: Int ) { // 次级构造函数,无需传入purchaseId constructor(productName: String, quantity: Int) : this( purchaseId = 0, // 临时占位值,不影响数据库生成主键 productName = productName, quantity = quantity ) }
转换函数直接调用次级构造函数:
fun PurchaseRequestDto.toPurchasedDataEntity(): PurchasedDataEntity { return PurchasedDataEntity( productName = this.productName, quantity = this.quantity ) }
方法3:使用Kotlin no-arg插件
如果你的项目允许配置插件,可以启用Kotlin的no-arg插件,让Micronaut Data能通过无参构造函数创建实体对象,再逐个设置字段:
首先在build.gradle.kts中配置插件:
plugins { kotlin("plugin.noarg") version "你的Kotlin版本号" } noArg { annotation("io.micronaut.data.annotation.MappedEntity") }
实体类保持主键非空:
@MappedEntity data class PurchasedDataEntity( @Id @GeneratedValue(GeneratedValue.Type.IDENTITY) val purchaseId: Long, val productName: String, val quantity: Int )
转换函数用apply方法赋值:
fun PurchaseRequestDto.toPurchasedDataEntity(): PurchasedDataEntity { return PurchasedDataEntity().apply { productName = this@toPurchasedDataEntity.productName quantity = this@toPurchasedDataEntity.quantity } }
推荐优先使用方法1,它最符合Kotlin和Micronaut Data的设计逻辑,代码简洁且无额外配置。
内容的提问来源于stack exchange,提问作者Aditya
相关产品推荐
相关产品推荐

