When using Kotlin and JPA + Hibernate and especially JPA inheritance, you will probably want to type check a polymorphic entity:
val request: RequestEntity = requestRepository.findById(123)
val response: ResponseEntity? = request.response // response is LAZY mapped
return when (response) {
null -> "pending"
is ResponseErrorEntity -> "error"
is ResponseRejectedEntity -> "rejected"
is ResponseAcceptedEntity -> "accepted"
}
You might be surprised to get following exception:
kotlin.NoWhenBranchMatchedException: null
After all, compiler told us, that this when
check is exhaustive.
The reason is, that the real type of response
value is something like ResponseAcceptedEntity$HibernateProxy$WS7APdlA
if (response != null) {
println(response::class)
println(response is ResponseAcceptedEntity)
}
// package.ResponseAcceptedEntity$HibernateProxy$WS7APdlA
// false
To fix this without changing the mapping from LAZY to EAGER, we use a handy utility function, implemented as a Kotlin extension:
@Suppress("UNCHECKED_CAST")
fun <T> T.unproxy(): T = Hibernate.unproxy(this) as T
We use it explicitly on all lazily mapped entities, than need to be checked by their type:
val response: ResponseEntity? = request.response.unproxy()