3

trying to use room with kotlin, not find official document. Here is some finding from the fails.

made it work for the simple cases but still not sure if it is the right way, so post it here and hope someone knows the office / right way to do it with kotlin?

got two issues, first one: when defining the entity it has to be put in the constructor and if not it will compile but not generate the xx_impl.java, like:

@Entity(name = "user")
class User {
    @ColumnInfo(name = "id") @PrimaryKey var id: String? = null
    @ColumnInfo(name = "name") var name: String? = null
    @ColumnInfo(name = "lastName") var lastName: String? = null
    @ColumnInfo(name = "age") var age: Int = 0
}

but if put in constructor

@Entity(tableName = "post")
class DbPost (

@ColumnInfo(name = "title")
var title: String? = null,

@ColumnInfo(name = "authorId")
var authorId: Int? = null,

@ColumnInfo(name = "date")
var date: String? = null,
) {
     @ColumnInfo(name = "id")
     @PrimaryKey(autoGenerate=true)
     var id: Int? = null
}

it will generates the xxx_impl.java (note, for different room versions, someone requires the fields to be initialized, in some version the last one cant have the default value, and in some version all params can be without initialization value, does anyone know what is the right way for it to work for all version -- maybe the latest version one.)

other issue is when the query has params, the compiler seems will put its own name for it in the generated xx_impl.java file (makes you dont know what to put in the code until after it generates the xx_impl.java), in different kotlin version it differs.

1. in one project grade it has apply plugin: 'kotlin-kapt'

and with kotlin_version = '1.1.2-4'

compile "android.arch.persistence.room:runtime:$rootProject.versions.arch_comp"
kapt "android.arch.persistence.room:compiler:1.0.0-alpha1"

@Query("select * from post where id = :id”)
fun findPostById(id: Long): DbPost

error: Each bind variable in the query must have a matching method parameter. Cannot find method parameters for :arg0.
e: 

e:     public abstract com.manijshrestha.todolist.data.DbPost findPostById(long p0);
                                                       ^

in there generated xxx_impl.java has used p0

@Override
public DbPost findPostById(long p0) {
    final String _sql = "select * from post where id = ?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    _statement.bindLong(_argIndex, p0);

2. in other project setting with kotlin_version = '1.1.3-2'

compile "android.arch.persistence.room:runtime:1.0.0-alpha1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"
kapt "android.arch.persistence.room:compiler:1.0.0-alpha1"

(note: if does not have kapt "android.arch.persistence.room:compiler:1.0.0-alpha1”, it will not generate the xxx_impl.java file)

when in the xxDao file put the query param with ‘:p0’

@Query("select * from post where id = :p0")
    fun loadPostById(id: Int): DbPost

it complains:

error: Each bind variable in the query must have a matching method parameter. Cannot find method parameters for :p0.
error: Unused parameter: arg0

in there generated xxx_impl.java it used arg0

@Override
public DbPost loadPostById(int arg0) {
    final String _sql = "select * from post where id = ?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    _statement.bindLong(_argIndex, arg0);
lannyf
  • 9,865
  • 12
  • 70
  • 152

1 Answers1

1

Properties in @Entity class should be added in constructor as it is also a default and suggested way of creating and initialising properties in Kotlin. This way you can insure that your room lib code will work on each versions. (I have used it and tried it in all release since Kotlin is official android language)).

For @Query methods in DAO class, parameters should be used like : arg0, arg1,..., argN.

@Query("select * from post where id = :arg0 and name like :arg1”)
fun findPostByIdName(id: Long, name: String): DbPost

Using @Query methods this way will avoid Each bind variable in the query must have a matching method parameter. Cannot find method parameters for :p0. error.

Kotlin has just release its 1.1.4 on 15th Aug(two days back), i am not sure if exact param names are allowed in this release or not.

I have not used apply plugin: 'kotlin-kapt' in my room-kotlin implementation. It wasn't working for me.

having this line kapt "android.arch.persistence.room:compiler:1.0.0-alpha1" is necessary because its annotation processor for Room lib and without it there is no meaning of annotations(like: @Entity, @DAO etc) used for Room implementation.

Check this article: https://medium.com/@chandilsachin/room-with-unit-test-in-kotlin-4ad31a39a291

Have a look at this stackoverflow question to have more insight: Room Persistence lib implementation in Kotlin

Hope it helps.

Sachin Chandil
  • 17,133
  • 8
  • 47
  • 65