You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+42Lines changed: 42 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -575,6 +575,48 @@ val customers: List<Customer> = Sql("SELECT * FROM customers").queryOf<Customer>
575
575
576
576
There are several other ways to do this, have a look at the [Custom Serializers](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serializers.md#custom-serializers) section kotlinx-serialization documentation for more information.
577
577
578
+
### Contextual Serialization for BigDecimal and UUID
579
+
580
+
When querying for types like `BigDecimal` or `UUID` directly (without wrapping them in a data class), you cannot use them as the direct result type in `queryOf<T>()`. This is because kotlinx-serialization requires all types to either be annotated with `@Serializable` or be marked as `@Contextual`, and these Java types cannot be annotated.
581
+
582
+
For example, this will **fail**:
583
+
```kotlin
584
+
// This will throw: Serializer for class 'java.math.BigDecimal' is not found
585
+
val total:BigDecimal=Sql("SELECT total FROM orders WHERE id = $id").queryOf<BigDecimal>().runOn(ctx)
586
+
```
587
+
588
+
The error you'll see:
589
+
```
590
+
kotlinx.serialization.SerializationException: Serializer for class 'java.math.BigDecimal' is not found.
591
+
Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.
592
+
```
593
+
594
+
**Why this happens:** Kotlin's serialization system uses compile-time code generation to create serializers for types marked `@Serializable`. For types that can't be annotated (like Java standard library classes), kotlinx-serialization provides a contextual serialization mechanism. However, this mechanism requires the type to be wrapped in a context that declares it as `@Contextual`.
595
+
596
+
**Solution:** Wrap the return type in a data class and use a `@Contextual` annotation:
597
+
598
+
```kotlin
599
+
@Serializable
600
+
data classBigDecimalWrapper(@Contextual valvalue:BigDecimal)
601
+
602
+
// Now this works:
603
+
val result:List<BigDecimalWrapper> =
604
+
Sql("SELECT total FROM orders WHERE id = $id").queryOf<BigDecimalWrapper>().runOn(ctx)
605
+
val total:BigDecimal= result.first().value
606
+
```
607
+
608
+
The same applies for `UUID`:
609
+
```kotlin
610
+
@Serializable
611
+
data classUuidWrapper(@Contextual valvalue:UUID)
612
+
613
+
val result:List<UuidWrapper> =
614
+
Sql("SELECT user_id FROM sessions WHERE token = $token").queryOf<UuidWrapper>().runOn(ctx)
615
+
val userId:UUID= result.first().value
616
+
```
617
+
618
+
Note that you can use `BigDecimal` and `UUID` directly as parameters in SQL queries without any wrapper since Terpal automatically handles encoding them (they're in the automatically-wrapped types list). The `@Contextual` wrapper is only needed when they appear as decoded result types.
619
+
578
620
### Custom Primitives
579
621
580
622
In some situations, with a custom datatype you may need to control how it is encoded in the database driver.
0 commit comments