Reputation: 1803
I am facing an unexpected error which I am not sure how to handle.
I have a data class like this:
data class Payload (
@SerializedName("id")
var id: String
@SerializedName("type")
var type: String,
@SerializedName("data")
var data: String
)
And a simple Spring controller like this:
@PostMapping("/some-endpoint")
fun dataHandler(@RequestBody payload: Payload): String{
when (payload.type){
"someType" -> {
val result = try {
gson.fromJson(payload.data, payloadData::class.java)
} catch (e: Exception){
throw BadDataException("Bad Data")
}
payloadProcessor.process(result, payload.id) // NPE here
}
"otherType" -> {
doSomethingElseHere()
}
}
}
When the execution reaches payloadProcessor.process, a null pointer exception occurs as id
is apparently null. On the other hand the object is created and the two remaining values seem to be properly populated.
If I add an if statement checking for null values, the ide complains that the the payload properties are never null, marking the if statement as redundant, but in reality this is not the case.
I was under the impression that null-safe properties are... well... null safe. At the very least I would expect the null pointer exception to occur once the object is constructed.
My question is:
Upvotes: 1
Views: 1526
Reputation: 5959
The issue is with Gson, not Spring. Gson is designed for use with Java, which has no* distinction between nullable and non-nullable types, so Gson will happily assign a null value anyways.
Unfortunately, there isn't a magic solution here. You can write your own TypeAdapter which explicitly checks for null values before constructing your data classes, but if you have a lot of classes, that's going to get very repetitive. Alternatively, you could create your own TypeAdapterFactory and use Kotlin's reflection library to check which types are nullable and which are not, but that will have various implications with regards to performance and dependencies.
* There are nullability annotations (@Nonnull, @Nullable), but Gson doesn't check them.
Upvotes: 1