Open zsiegel opened 5 months ago
Note that I am currently working around this right now by using a TypeConverter. But I have a number of entities that may return a single item from time to time and this is a bit cumbersome.
I was looking around to see if I could submit a PR myself but I am a little lost figuring out where the root of the issue might be.
@Factory
class TypeConverters {
@Singleton
fun myEntityToFlow(): TypeConverter<MyEntity, Flow<MyEntity>> {
return TypeConverter<MyEntity, Flow<MyEntity>> { `object`, targetType, context ->
Optional.of(flowOf(`object`))
}
}
}
I am also seeing some interesting and unexpected behavior when the return is empty. I would expect to get back an empty Flow
but instead I get a null object even though the return type is Flow
.
Do you have micronaut-kotlin
dependency included?
I have the following dependencies related to kotlin specified.
implementation("io.micronaut.kotlin:micronaut-kotlin-extension-functions")
implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
Try also to add:
org.jetbrains.kotlinx:kotlinx-coroutines-reactive
or maybe org.jetbrains.kotlinx:kotlinx-coroutines-reactor
Yes I have the first one. I tried adding org.jetbrains.kotlinx:kotlinx-coroutines-reactor
and have the same issue.
Testing this out a bit more I think I was able to determine that this only happens with interface methods that use the @Query
annotation. The findAll()
and other built-in methods seem to return reactor types, but the custom @Query
annotation does not?
I have solved this problem with the following factory that handles the conversion for any single object and any list of objects.
@Factory
class TypeConverters {
@Singleton
fun listToFlow(): TypeConverter<List<Any>, Flow<Any>> {
return TypeConverter<List<Any>, Flow<Any>> { `object`, targetType, context ->
Optional.of(flowOf(`object`))
}
}
@Singleton
fun anyToFlow(): TypeConverter<Any, Flow<Any>> {
return TypeConverter<Any, Flow<Any>> { `object`, targetType, context ->
Optional.of(flowOf(`object`))
}
}
}
I am not sure if this makes sense to contribute or if I have properly diagnosed things. I am not sure what the different is between the built-in default methods and using @Query
My implementation above was in correct. I am now trying.
@Factory
class TypeConverters {
@Singleton
fun listToFlow(): TypeConverter<List<Any>, Flow<Any>> {
return TypeConverter<List<Any>, Flow<Any>> { `object`, targetType, context ->
Optional.of(`object`.asFlow())
}
}
@Singleton
fun anyToFlow(): TypeConverter<Any, Flow<Any>> {
return TypeConverter<Any, Flow<Any>> { `object`, targetType, context ->
Optional.of(flowOf(`object`))
}
}
}
In addition I am not able to get more than 1 result from the flow. This might be user error but I am struggling a bit to see what might be going wrong here.
Expected Behavior
When using a return type of Flow and when the given query only returns one result I expect the conversion to work to return a Flow that emits a single item.
Actual Behaviour
When the query returns a single item. Micronaut fails to convert that entity to a Flow.
Steps To Reproduce
CoroutineCrudRepository<MyEntity, Long>
repository and entityMyEntity
..findAll()
query after inserting a single row.Environment Information
MacOS 14.4
openjdk 17.0.1 2021-10-19 LTS OpenJDK Runtime Environment Zulu17.30+15-CA (build 17.0.1+12-LTS) OpenJDK 64-Bit Server VM Zulu17.30+15-CA (build 17.0.1+12-LTS, mixed mode, sharing)
Example Application
No response
Version
4.3.7