Kotlin – type checking Hibernate entities

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()

Leave a Reply

Your email address will not be published. Required fields are marked *