プロジェクトを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 からそう遠くない
それを解決する方法のアイデアは?
以前にも同様の問題がありました。
まず、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はそれらを認識しません。
次のようなセカンダリコンストラクターを指定する必要があります。
@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)
}
私のために働いたもの:
@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
)
私はそれを解決するための良い選択肢だと思います:
@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
)
Kotlinではパラメーター名として長い名前を使用できますが、部屋がJavaコードを生成する場合、これは機能しません。
あなたの場合は問題ではありませんが、他の人にとっては、コンストラクタに@Ignore paramsがある場合、この部屋で発生する可能性があります。
例えば:
@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)
私にとってしなければならないことは、データクラスにコンストラクタを追加することだけで、空のパラメータが次のように送信されました。
@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("","","","","","","")
}
私もこの問題を抱えていましたが、問題は、タイプコンバーターが既にあるプロパティに@Embedded注釈を追加したことであるため、同じ問題を抱えている人はモデルクラスのプロパティ宣言を慎重に確認し、@埋め込み注釈は、それに関連付けられた型コンバーターを持つプロパティにはありません。
ライブラリのバグであることが判明しました https://github.com/googlesamples/Android-architecture-components/issues/49
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()
)
私はこの問題を抱えていました(OPのような関連する非プリミティブアイテムのリストが含まれているエンティティ(すべてのフィールドは適切に初期化されていますvar
sはここでの回答の多くが示唆しています) 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スレッド には、この誤解を招くエラーに関する詳細情報がありますが、問題がまだ修正されているかどうかはわかりません。
私にとっては、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) {
}
エラーを引き起こすコンストラクタに以下の注釈を追加し、新しい空のコンストラクタを追加します。
@無視
データクラスには使用せず、代わりに通常のクラスを使用します。この方法は問題を解決します
2.1.0-alpha6では、Daoでは無効な戻り値型であることが判明しました。期待どおりに戻り型を修正すると修正されました。
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
// ...
}
同じバグ、もっと奇妙な解決策:Daoでreactx Maybe<Cursor>
を使用してカーソルを返さないでください。 Flowable
、Single
、および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