Постоянство помещения: ошибка: сущности и Pojos должны иметь полезный публичный конструктор
Я конвертирую проект в Kotlin, и я пытаюсь сделать свою модель (которая также является моей сущностью) классом данных
Я намерен использовать Moshi для преобразования ответов JSON из API
@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
)
Я не могу создать причину приложения следующей ошибки
Сущности и Pojos должны иметь полезный публичный конструктор. У вас может быть пустой конструктор или конструктор, параметры которого соответствуют полям (по имени и типу). Невозможно найти установщик для поля.
Примеры, которые я нашел, находятся недалеко от this
Идеи о том, как его решить?
Ответы
Ответ 1
Раньше была аналогичная проблема.
Сначала я обновил/добавил apply plugin: 'kotlin-kapt'
в gradle.
Затем я использовал его вместо annotationProcessor
в gradle:
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
)
UPDATE:
Это решение работает, когда у вас есть классы для модели и классы для базы данных в одном Android-модуле. Если у вас есть классы моделей в модуле библиотеки Android и остальная часть кода в вашем основном модуле, Room НЕ узнает их.
Ответ 2
вам нужно указать дополнительный конструктор, например:
@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)
}
Ответ 3
Что сработало для меня:
@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
Я думаю, что это хороший вариант для решения:
@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
)
Ответ 5
Kotlin разрешает указывать имя параметра, но это не сработает, когда room генерирует код Java.
Ответ 6
Для меня все, что мне нужно было сделать, это добавить конструктор в класс данных с пустыми параметрами, отправленными ему следующим образом:
@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("","","","","","","")
}
Ответ 7
У меня также была эта проблема, но я понял, что проблема заключалась в том, что я добавил аннотацию @Embedded к свойству, в котором уже был преобразователь типа, поэтому любой, кто сталкивается с такой же проблемой, должен внимательно проверить объявления свойств для вашего класса модели и убедиться, что @Встроенная аннотация не относится к свойству, с которым связан конвертер типов.
Ответ 8
Это оказалось ошибкой в библиотеке
https://github.com/googlesamples/android-architecture-components/issues/49
Ответ 9
https://issuetracker.google.com/issues/62851733
Я нашел, что это ошибка @Relation проекции!
не проблема языка Котлина.
основанный на 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()
)
Ответ 10
У меня была эта проблема с сущностью (все поля были должным образом инициализированы var
как предлагают многие ответы здесь), которая включала список связанных, не примитивных элементов, таких как OP в этом вопросе 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.
Поэтому мое решение было очень похоже на этот ответ
Эта ветка github, посвященная компонентам архитектуры Google, содержит больше информации об этой вводящей в заблуждение ошибке, но не уверена, была ли проблема устранена.
Ответ 11
Та же ошибка, гораздо более странное решение: не возвращайте курсор, используя реактивный ключ Maybe<Cursor>
на вашем Дао. Flowable
, Single
и Observable
тоже не работали.
Просто укусите пулю и сделайте ответный вызов вне запроса Дао. До:
@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
Ответ 12
Просто добавьте приведенную ниже аннотацию к любому конструктору, который вызывает ошибки, и добавьте новый пустой конструктор.
@Ignore
Ответ 13
Как указано в номере базы данных 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
// ...
}
Ответ 14
Не используйте для dataclass, вместо этого используйте обычный класс. Этот метод решит проблему
Ответ 15
В версии 2.1.0-alpha6 это был неверный тип возврата в Dao. Исправление типа возврата, как и ожидалось, исправило его.
Ответ 16
Для меня я использовал 'lat' & 'long' в качестве имени переменной в классе данных (Entity) для kotlin, поэтому переименование в широту и долготу это сработало.
Не работает:
@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) {
}
Ответ 17
В вашем случае это не проблема, но для других эта ошибка может возникнуть, если в вашем конструкторе есть параметры @Ignore, т.е. Room ожидает иметь либо:
- конструктор без параметров или
- конструктор со всеми полями, не помеченными @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)