Open bfg opened 3 months ago
I've managed to work around this with the following annotation on the entity class:
@KonvertTo(
IAPDefinitionDto::class,
mappings = [
Mapping(target = "createdAt", expression = "it.createdAt!!.truncatedTo(java.time.temporal.ChronoUnit.MILLIS).atZone(java.time.ZoneOffset.UTC)"),
],
options = [
Konfig(key = ENFORCE_NOT_NULL, value = "true"),
Konfig(key = ENABLE_CONVERTERS, value = "true")
],
mapFunctionName = "toDto"
)
it works, but I generally don't like this approach on actual classes, I prefer to have entity mapping code in the same place.
Interesting finding, never had a problem like this. I did some research about the error (you probably did so, too) and stumbled upon this comment https://github.com/google/ksp/issues/427#issuecomment-906006403. Not sure if this is a konvert issue, a KSP issue, a micronaut issue or a gradle issue. Feels like it could be anything :confused:
Regarding a custom TypeConverter
: I know this is not yet documented well, but it should be pretty straightforward:
Create your custom TypeConverter
like this:
@AutoService(TypeConverter::class)
class InstantToZonedDateTimeConverter : AbstractTypeConverter() {
override val enabledByDefault: Boolean = true
private val sourceType: KSType by lazy {
resolver.getClassDeclarationByName(Instant::class.qualifiedName!!)!!.asStarProjectedType()
}
private val targetType: KSType by lazy {
resolver.getClassDeclarationByName(ZonedDateTime::class.qualifiedName!!)!!.asStarProjectedType()
}
override fun matches(source: KSType, target: KSType): Boolean {
return handleNullable(source, target) { sourceNotNullable, targetNotNullable ->
sourceType.isAssignableFrom(sourceNotNullable) && targetType == targetNotNullable
}
}
override fun convert(fieldName: String, source: KSType, target: KSType): CodeBlock {
val sourceNullable = source.isNullable()
val nc = if (sourceNullable) "?" else ""
return CodeBlock.of(
"$fieldName$nc.truncatedTo(%T.MILLIS)$nc.atZone(%T.UTC)" + appendNotNullAssertionOperatorIfNeeded(source, target),
ChronoUnit::class,
ZoneOffset::class
)
}
}
Important :warning:: If you do not want to use the `@AutoService` KSP stuff, you have to manually create the necessary file. To do so, create a `META-INF/services/io.mcarle.konvert.converter.api.TypeConverter` file in resources and add the FQN to the `InstantToZonedDateTimeConverter` class.
4. In your project where you want to use the `TypeConverter`, add the newly generated module as a KSP dependency `ksp(project(":custom-type-converter"))` (next to the konvert one).
Afterwards you can delete the function `instantToZonedDateTime`.
Tip: If you want to set your konvert configurations globally, you can further amend your `build.gradle` and define them like this (see e.g. https://github.com/mcarleio/konvert/blob/main/example/build.gradle.kts#L52):
```kotlin
ksp {
arg("konvert.enforce-not-null", "true")
arg("konvert.konverter.generate-class", "true")
arg("konvert.add-generated-konverter-annotation", "false")
}
I'll create a reproducer and share it on gh.
Thanks for a great feedback, I was suspecting whether type converter should be in it's own jar, and well, you've confirmed it.
I wanted to use custom mappings and failed to make my custom
TypeConverter
initialize from within the project, so I've decided to create an interface with default methods to do the custom mappings.The following code results in a compilation error, if
instantToZonedDateTime()
is commented out, compilation finishes successfully.I'm not sure whether this is a micronaut or konvert ksp processor issue, full details are here: https://github.com/micronaut-projects/micronaut-core/issues/11058