Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

There are multiple good constructors and Room will pick the no-arg constructor. How to solve this warning

I try to implement Room Persistent Database library in android kotlin project, but catch this warning at compile time. I don't know how to solve this warring.

warning: There are multiple good constructors and Room will pick the no-arg constructor. You can use the @Ignore annotation to eliminate unwanted constructors.

Auto Generated Class

public final class Gender {
             ^

Kotlin Data Class

import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey

@Entity
data class Gender(@PrimaryKey(autoGenerate = true)
             var genderId: Int = 0,
             var type: String = "")
like image 628
Kishan Donga Avatar asked Oct 25 '18 07:10

Kishan Donga


People also ask

Why are there no args constructors?

Here, the constructor does not accept any parameters. Hence, it is known as a no-arg constructor. Notice that we have declared the constructor as private. Once a constructor is declared private , it cannot be accessed from outside the class.

Can you have multiple constructors?

The technique of having two (or more) constructors in a class is known as constructor overloading. A class can have multiple constructors that differ in the number and/or type of their parameters. It's not, however, possible to have two constructors with the exact same parameters.

Can one class have multiple constructors?

There can be multiple constructors in a class. However, the parameter list of the constructors should not be same. This is known as constructor overloading.


3 Answers

I had the same warning and I just put the @Ignore before my empty constructor

// Empty constructor
@Ignore
public Room_Database() {
}
like image 58
toskan Avatar answered Oct 09 '22 23:10

toskan


Try this:

import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey

@Entity
class Gender @Ignore constructor(@PrimaryKey(autoGenerate = true)
             var genderId: Int = 0,
             var type: String = "") {

    constructor() : this(0, "")
}

Like the warning says

(...) Room will pick the no-arg constructor. (...)

Your constructor does have two arguments. You needed to add an empty one and ignore the other

like image 24
Er1 Avatar answered Oct 09 '22 23:10

Er1


The "problem" here is that kotlin is generating multiple constructors for your class, given that you have default parameters for some of the properties.

In your case you have:

// this is the synthetic one, don't worry to much about it
public Gender(int var1, String var2, int var3, DefaultConstructorMarker var4) { /* some implementation */ }

// the "default" one, that can be called when you are delegating to the default params
public Gender() { /* some implementation */ }

// the one that gets all the params
public Gender(int genderId, @NotNull String type) { /* some implementation */ }

Room could be using either the one without parameters, or the one with two, and it's choosing one of them (and letting you know via that warning)

You can remove the default parameter for type, and there will be only one (non-synthetic) constructor:

// still synthetic
public Gender(int var1, String var2, int var3, DefaultConstructorMarker var4) { /* some implementation */ }

// this is the only usable constructor now
public Gender(int genderId, @NotNull String type) { /* some implementation */}

Now Room has only one constructor to use, so it will use it happily.

If your use case allows it, you can just remove the default values. Note that you could only do it for the non-primitive types, which make make your API nicer.

I don't know about your particular case, but note that you could also use val instead of var

@Entity
data class Gender(
    @PrimaryKey(autoGenerate = true)
    val genderId: Int = 0,  // so callers don't need to specify an id. Room will generate one if it gets a 0 here
    var type: String
)
like image 1
marianosimone Avatar answered Oct 09 '22 21:10

marianosimone