GoogleCloudPlatform / GoogleCloudPlatform/spring-cloud-gcp
Generics not correctly deserialized for Spanner JSON columns
- Dominant language
- Java
- Stars
- 551
- Forks
- 349
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 14
Description
**Describe the bug**
Deserializing generic types with spring cloud gcp spanner does not work.
If I have classes like this:
```kotlin
@Table(name = "MyEntity")
class MyEntity (
val id: String,
@Column(name = "jsonField", spannerType = TypeCode.JSON)
val myGenericJsonField: GenericType,
)
data class GenericType (
val genericField: T
)
data class SimpleType(
val test: String
)
```
with the following schema:
```sql
CREATE TABLE IF NOT EXISTS MyEntity(
id STRING(36) PRIMARY KEY,
jsonField JSON
)
```
After writing to spanner and reading the entity back it will not restore the generic type correctly. So instead of `genericField` being `SimpleType`, it fills it with a `com.google.gson.internal.LinkedTreeMap`.
The problem seems to be that in `SpannerPersistenPropertyImpl.getColumnInnerType` not the whole `TypeInformation` is preserved, so later there is no way to give gson a `TypeToken` to actually reconstruct the correct type.
**Sample**
There is a reproduction repo here: https://github.com/hesch/spring-cloud-gcp-generic-repro
With a test that fails here: https://github.com/hesch/spring-cloud-gcp-generic-repro/blob/main/src/test/kotlin/org/example/GenericTest.kt
Contributor guide
Research direction
Start with SpannerPersistenPropertyImpl.getColumnInnerType and the failing GenericTest.kt in the linked reproduction repository. Trace the Spanner JSON deserialization path and use that test to verify that a round trip preserves GenericType instead of producing a LinkedTreeMap.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- google-cloud, kotlin, spring
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100