web-dev-qa-db-ja.com

ルームの永続性:エラー:エンティティとPojoには、使用可能なパブリックコンストラクターが必要です

プロジェクトをKotlinに変換しています。モデル(これもエンティティです)をMoshiを使用してAPIからのJSON応答を変換するデータクラスにしようとしています。

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String,
    var overview: String,
    var poster_path: String,
    var backdrop_path: String,
    var release_date: String,
    var vote_average: Double,
    var isFavorite: Int
)

次のエラーの原因をアプリを構築できません

エンティティとPojoには、使用可能なパブリックコンストラクターが必要です。空のコンストラクターまたはパラメーターがフィールドに一致するコンストラクター(名前とタイプによる)を持つことができます。フィールドのセッターが見つかりません。

私が見つけた例は this からそう遠くない

それを解決する方法のアイデアは?

42
Leonardo Deleon

以前にも同様の問題がありました。

まず、apply plugin: 'kotlin-kapt'をgradleに更新/追加しました。

次に、私はgradleでannotationProcessorの代わりにそれを使用しました:

kapt "Android.Arch.persistence.room:compiler:1.0.0-alpha4"

最後に、不変のデータクラスを作成しました。

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    val id : Int,
    val title: String,
    val overview: String,
    val poster_path: String,
    val backdrop_path: String,
    val release_date: String,
    val vote_average: Double,
    val isFavorite: Int
)

更新:

このソリューションは、同じAndroidモジュールにモデルのクラスとデータベースのクラスがある場合に機能します。 Androidライブラリモジュールにモデルクラスがあり、メインモジュールに残りのコードがある場合、Roomはそれらを認識しません。

40
Tomek Polański

次のようなセカンダリコンストラクターを指定する必要があります。

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String,
    var overview: String,
    var poster_path: String,
    var backdrop_path: String,
    var release_date: String,
    var vote_average: Double,
    var isFavorite: Int
) {
    constructor() : this(0, "", "", "", "", "", 0.0, 0)
}    
16
evanchooly

私のために働いたもの:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int? = 0,
    var title: String? = "",
    var overview: String? = "",
    var poster_path: String? = "",
    var backdrop_path: String? = "",
    var release_date: String? = "",
    var vote_average: Double? = 0.0,
    var isFavorite: Int? = 0
)
9
stevenwood

私はそれを解決するための良い選択肢だと思います:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int = 0,
    var title: String = "",
    var overview: String = "",
    var poster_path: String = "",
    var backdrop_path: String = "",
    var release_date: String = "",
    var vote_average: Double = 0.0,
    var isFavorite: Int = 0
)
4
tito

Kotlinではパラメーター名として長い名前を使用できますが、部屋がJavaコードを生成する場合、これは機能しません。

3
Erik B

あなたの場合は問題ではありませんが、他の人にとっては、コンストラクタに@Ignore paramsがある場合、この部屋で発生する可能性があります。

  • パラメータなしのコンストラクタまたは
  • @Ignoreでマークされていないすべてのフィールドを持つコンストラクター

例えば:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String,
    @Ignore var overview: String) 

動作しないでしょう。この意志:

@Entity(tableName = "movies")
data class MovieKt(
    @PrimaryKey
    var id : Int,
    var title: String) 
3
daneejela

私にとってしなければならないことは、データクラスにコンストラクタを追加することだけで、空のパラメータが次のように送信されました。

    @Entity(tableName = "posts")
data class JobPost(
    @Ignore
    @SerializedName("companyLogo")
    var companyLogo: String,
    @Ignore
    @SerializedName("companyName")
    var companyName: String,
    @Ignore
    @SerializedName("isAggregated")
    var isAggregated: String,
    @PrimaryKey(autoGenerate = false)
    @SerializedName("jobID")
    var jobID: String,
    @Ignore
    @SerializedName("jobTitle")
    var jobTitle: String,
    @Ignore
    @SerializedName("postedOn")
    var postedOn: String,
    @Ignore
    @SerializedName("region")
    var region: String
) {
    constructor() : this("","","","","","","")
}
3
Ahmed Awad

私もこの問題を抱えていましたが、問題は、タイプコンバーターが既にあるプロパティに@Embedded注釈を追加したことであるため、同じ問題を抱えている人はモデルクラスのプロパティ宣言を慎重に確認し、@埋め込み注釈は、それに関連付けられた型コンバーターを持つプロパティにはありません。

2
caleb grimah

ライブラリのバグであることが判明しました https://github.com/googlesamples/Android-architecture-components/issues/49

1
Leonardo Deleon

https://issuetracker.google.com/issues/628517

これは@Relationのprojectionバグだとわかりました! Kotlin言語の問題ではありません。ベースのGoogle GithubBrowserSample Javaもエラーが発生しましたが、エラーメッセージが異なります。

以下は私のkotlinコードです:

data class UserWithCommunities(
        @Embedded
        var user: User = User(0, null),

        @Relation(parentColumn = "id",
                entityColumn = "users_id",
                entity = CommunityUsers::class,
                projection = arrayOf("communities_id")) // delete this line.
        var communityIds: List<Int> = emptyList()
)

右:

data class UserWithCommunities(
        @Embedded
        var user: User = User(0, null),

        @Relation(parentColumn = "id",
                entityColumn = "users_id",
                entity = CommunityUsers::class)
        var communityList: List<CommunityUsers> = emptyList()
)
1
changhao cui

私はこの問題を抱えていました(OPのような関連する非プリミティブアイテムのリストが含まれているエンティティ(すべてのフィールドは適切に初期化されていますvarsはここでの回答の多くが示唆しています) SO質問 持っていました。例えば:

@Entity(tableName = "fruits")
data class CachedFruitEntity(
        @PrimaryKey var id: Long = 0L,
        @Embedded(prefix = "buyer_") var buyerEntity: CachedBuyerEntity? = null
        @TypeConverters(VendorsConverter::class)
        var vendorEntities: List<CachedVendorEntity?> = listOf()))

つまり、埋め込みフィールドがあり、実際に必要なのはベンダーエンティティリストの型コンバーターであることに気づくまでに少し時間がかかりました(コンパイラーは通常のError:(58, 31) error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.を投げていなかったので、私の解決策は この回答 と非常によく似ています

この googleアーキテクチャコンポーネントgithubスレッド には、この誤解を招くエラーに関する詳細情報がありますが、問題がまだ修正されているかどうかはわかりません。

1
kip2

私にとっては、kotlinのdata(Entity)クラスで変数名として「lat」と「long」を使用していたため、機能する緯度と経度に名前を変更しました。

動作していません:

@Entity(tableName = "table_User")
data class User(@PrimaryKey var userId : Int, @ColumnInfo(name = "first_name") 
var firstName: String
            , @ColumnInfo(name = "last_name") var lastName: String
            , @ColumnInfo(name = "password") var password: String
            , @ColumnInfo(name = "dob") var dob: Long
            , @ColumnInfo(name = "address") var address: String
            , @ColumnInfo(name = "lat") var latitude: Double
            , @ColumnInfo(name = "long") var longitude: Double) {

}

ワーキング:

@Entity(tableName = "table_User")
data class User(@PrimaryKey var userId : Int, @ColumnInfo(name = "first_name") 
var firstName: String
            , @ColumnInfo(name = "last_name") var lastName: String
            , @ColumnInfo(name = "password") var password: String
            , @ColumnInfo(name = "dob") var dob: Long
            , @ColumnInfo(name = "address") var address: String
            , @ColumnInfo(name = "latitude") var latitude: Double
            , @ColumnInfo(name = "longitude") var longitude: Double) {

}
0

エラーを引き起こすコンストラクタに以下の注釈を追加し、新しい空のコンストラクタを追加します。

@無視

0
Harbdollar

データクラスには使用せず、代わりに通常のクラスを使用します。この方法は問題を解決します

0
Mustafa

2.1.0-alpha6では、Daoでは無効な戻り値型であることが判明しました。期待どおりに戻り型を修正すると修正されました。

0
Vairavan

Room Database Entity に記載されているとおり:

各エンティティには、引数なしのコンストラクターまたはパラメーターがフィールドに一致するコンストラクター(タイプと名前に基づく)が必要です。

したがって、空のコンストラクターを追加し、@Ignoreでパラメーター化されたコンストラクターに注釈を付けると、問題が解決します。例:

public class POJO {

    long id;

    String firstName;

    @Ignore
    String lastName;

    public POJO() {
    }

    @Ignore
    public POJO(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    // getters and setters
    // ...

}
0
Rajarshi

同じバグ、もっと奇妙な解決策:Daoでreactx Maybe<Cursor>を使用してカーソルを返さないでください。 FlowableSingle、およびObservableも機能しませんでした。

弾丸をかむだけで、Daoリクエストの外部でリアクティブコールを行います。前:

@Dao
interface MyDao{
    @Query("SELECT * FROM mydao")
    fun getCursorAll(): Flowable<Cursor>
}

後:

@Dao
interface MyDao{
    @Query("SELECT * FROM mydao")
    fun getCursorAll(): Cursor
}

メタ:

Android Studio 3.2
Build #AI-181.5540.7.32.5014246, built on September 17, 2018
JRE: 1.8.0_152-release-1136-b06 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
macOS 10.12.6
0
Blaze Gawlik