Solving Room "cannot find setter for field" error in build time


Room persistence library is one of the easiest one to set up. However, when using data classes for your Room entities, you might face some small problem, which on the first look doesn't really make any sense.

Let's try to compile this class:

The problem:

And so will happen with other fields

But I already have a data class entity that has only vals.  Why doesn't this class compile?
The problem here is the class UserGrade that room has no idea how give a value to it. Furthermore, that's a non nullable type. Even though I'm ignoring it from Room, the compiler cannot continue because it's the constructor that is checked first, thus failing all my other values to be set.

So, a small fix for this, is that make every variable a var instead of val and make our object nullable type. It's not a bad solution, but now I have to define a constructor, to tell Room that these are the default values from it: 



The solution

Perhaps it is not such a big deal, but when chances are, why not try a better approach? Also, it might be a little problematic to break the standardization of the entities. Having a data class with vals and a data class with vars for the same purpose, is not a good style, at least for me. 


Let's re roll to immutable variables and place a default value on our UserGrade object:


If you try to build, the same error will appear. The compiler will still yell at you. Even though the problem still persists from Room library, it's not its fault. That's because when Kotlin compiles to Java, it has no idea what default values in parameters are.  

The last approach of this use case is to add the @JvmOverloads annotation before the constructor, so Java will know to create the constructor overloading for us:



And that's it. Good luck!

You can follow me on twitter.