Kotlin lazy property in data class results in NullPointerException

Viewed 48

I have a Kotlin interface that looks like this:

interface IGeneralData {
    val id: Int
    val name: String
}

and a data class implementing IGeneralData which is created by either GSON or Jetpack Room:

@Entity
data class MyData(
    @PrimaryKey override val id: Int,
    override val name: String
) : IGeneralData {
    @delegate:Ignore
    val last: String by lazy {
        name.substring(name.lastIndexOf('.') + 1)
    }
}

Unfortunately, I get a NullPointerException that I don't understand when accessing the last property:

java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object kotlin.Lazy.getValue()' on a null object reference

When I look at the object in the debugger, at the time of accessing last, both the id field and the name field are populated. So where does this NPE come from?

The following version with a getter works just fine:

@Entity
data class MyData(
    @PrimaryKey override val id: Int,
    override val name: String
) : IGeneralData {
    val last: String
        @Ignore
        get() {
            return name.substring(name.lastIndexOf('.') + 1)
        }
}

Thank you!

1 Answers

This is just a guess, but I think Ignore fixes the issue for Room, but for GSON you need to use Transient. So you need both annotations:

@Entity
data class MyData(
    @PrimaryKey override val id: Int,
    override val name: String
) : IGeneralData {
    @delegate:Ignore 
    @delegate:Transient
    val last: String by lazy {
        name.substring(name.lastIndexOf('.') + 1)
    }
}
Related