Cannot have mixed type fields
- Dominant language
- Java
- Stars
- 24.2k
- Forks
- 4.5k
- Avg merge
- 6d 4h
- Merged PRs (30d)
- 12
Description
I'm currently faced with a JSON model that has a field whose type depends on the direction (serialization vs deserialization).
I have the following class:
```
data class MyModel(val id: String?) {
@JsonExcludeSerialize
@SerializedName("data") private var _dataIn: List = listOf()
@JsonExcludeDeserialize
@SerializedName("data") private var _dataOut: List = listOf()
}
```
I also created following exclusion strategy and annotations:
```
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
annotation class JsonExcludeSerialize
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
annotation class JsonExcludeDeserialize
class JsonExcludeStrategy(private val direction: JsonExcludeStrategy.Direction) : ExclusionStrategy {
enum class Direction { SERIALIZE, DESERIALIZE }
private fun annotationMeansSkip(annotation: Annotation): Boolean {
if (direction == Direction.SERIALIZE && annotation is JsonExcludeSerialize) return true
if (direction == Direction.DESERIALIZE && annotation is JsonExcludeDeserialize) return true
return false
}
override fun shouldSkipField(f: FieldAttributes): Boolean {
return f.annotations.firstOrNull { annotationMeansSkip(it) } != null
}
override fun shouldSkipClass(clazz: Class<*>): Boolean {
return clazz.annotations.firstOrNull { annotationMeansSkip(it) } != null
}
}
```
And registered with:
```
gson = GsonBuilder()
.addSerializationExclusionStrategy(JsonExcludeStrategy(JsonExcludeStrategy.Direction.SERIALIZE))
.addDeserializationExclusionStrategy(JsonExcludeStrategy(JsonExcludeStrategy.Direction.DESERIALIZE))
.create()
```
Unfortunately I hit the following exception:
```
java.lang.IllegalArgumentException: class com.me.app.MyModel declares multiple JSON fields named data
```
This shouldn't be an issue since one `data` field is used for serialization and the other is used for deserialization.
I traced the issue to the line 168 in the following block:
https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java#L163:L170
Since all `BoundField`s are indexed by their json field name `LinkedHashMap.put` will return the previously registered `data` field when the second comes up and raise an exception. Maybe a `LinkedHashSet` could be used instead with a custom `equalTo` implementation on `BoundField` to determine collision.
I am not versed enough in Java to submit a pull request hence the long details and possible solution above.
Thanks for considering and in the mean time if anybody has a workaround I would appreciate it.
Contributor guide
Assessment
This issue has not been assessed yet.