Как определить @Relation класса, который содержит поле / свойство @Embedded в Room (Android) - PullRequest
0 голосов
/ 24 января 2019

Я делаю приложение для управления личными финансами.Я использую Room для создания базы данных.Сейчас у меня 5 POJOS, все они помечены как @Entity.Payment, Balance, Attachment, Account and Category.Вот как связаны классы:

Платеж имеет список остатков и вложений.Эти два класса имеют paymentId для установления отношения.Payment также имеет поле для categoryId (я не собираюсь помещать весь код из классов и класса Attachment, чтобы сделать этот пост максимально коротким)

Оплата

@Entity(tableName = Payment.TABLE_NAME)
@TypeConverters(BigAmountConverter::class, DateTimeConverter::class)
@Parcelize
class Payment(
    @PrimaryKey
    @ColumnInfo(name = COLUMN_ID)           var id: String = "p_"+UUID.randomUUID().toString(),
    @Ignore                                 var sheetRow: Int = 0,
    @ColumnInfo(name = COLUMN_PAYMENT_TYPE) var typeOfPayment: Int = 0,
    @ColumnInfo(name = COLUMN_NAME)         var name: String = "",
    @ColumnInfo(name = COLUMN_DESCRIPTION)  var description: String = "",
    @Ignore                                 var amount: BigDecimal = BigDecimal.ZERO,
    @ColumnInfo(name = COLUMN_CURRENCY)     var currency: String = "",
    @ColumnInfo(name = COLUMN_PLACE)        var place: String = "",
    @ColumnInfo(name = COLUMN_DATE)         var date: DateTime = DateTime.now(),
    @ColumnInfo(name = COLUMN_LOCATION)     var location: LatLng = Place.DEFAULT_LOCATION,
    @ColumnInfo(name = COLUMN_CATEGORY)     var category: Category = Category.UNKNOWN,
    @ColumnInfo(name = COLUMN_DATE_ADDED)   var Date_added: DateTime = DateTime.now(),
    @ColumnInfo(name = COLUMN_DATE_MODIFIED)var Date_modified: DateTime = DateTime.now(),
    @ColumnInfo(name = COLUMN_STATUS)       var status: Int = DRAFT_STATUS,
    @ColumnInfo(name = COLUMN_GROUP)        var group: Group = Group(),
    @ColumnInfo(name = COLUMN_USER)         var user: String = ""):Parcelable...

Баланс в дополнение к paymentId, имеет поле для accountId

Баланс

@Entity(tableName = Balance.TABLE_NAME,
    foreignKeys = arrayOf(
            ForeignKey(entity = Payment::class,
                    parentColumns = arrayOf(Payment.COLUMN_ID),
                    childColumns = arrayOf(Balance.COLUMN_PAYMENT_ID),
                    onDelete = ForeignKey.CASCADE)),
    indices = arrayOf(Index(Balance.COLUMN_PAYMENT_ID), Index(Balance.COLUMN_ACCOUNT_ID)))
@TypeConverters(BigExchangeRateConverter::class, DateConverter::class)
@Parcelize
data class Balance(
    @PrimaryKey
    @ColumnInfo(name = COLUMN_ID)           var id: String = "b_"+UUID.randomUUID().toString(),
    @ColumnInfo(name = COLUMN_PAYMENT_ID)   var paymentId: String = "",
    @ColumnInfo(name = COLUMN_ACCOUNT_ID)   var account: Account = Account(),
    @ColumnInfo(name = COLUMN_AMOUNT)       var amount: BigDecimal = BigDecimal.ZERO,
    @ColumnInfo(name = COLUMN_EXCHANGE)     var exchangeRate: BigDecimal = BigDecimal.ONE,
    @ColumnInfo(name = COLUMN_DATE)         var date: Date = Date(),
    @ColumnInfo(name = COLUMN_STATUS)       var status: Int = 1,
    @Ignore                                 var sheetRow: Int = 0) : Parcelable...

Счет

@Entity (tableName = Account.TABLE_NAME)
@Parcelize
data class Account(
    @PrimaryKey
    @ColumnInfo(name = COLUMN_ID) var id: Int = 0,
    @ColumnInfo(name = COLUMN_NAME) var name: String = "",
    @ColumnInfo(name = COLUMN_CURRENCY_ISO) var currencyISO: String = "",
    @ColumnInfo(name = COLUMN_COLOR)        var color: Int = fromHexColortoIntColor("#3e70c1"),
    @ColumnInfo(name = COLUMN_TYPE)         var type: Int = ACCOUNT_TYPE_CASH,
    @ColumnInfo(name = COLUMN_SHARED_SHEET) var publicSheetId: String = "",
    @ColumnInfo(name = COLUMN_EMAIL)        var email: String = "",
    @ColumnInfo(name = COLUMN_STADISTICS)   var stadistics: Boolean = true,
    @ColumnInfo(name = COLUMN_IMAGE)        var imageURL: String = "",
    @ColumnInfo(name = COLUMN_STATUS)       var status: Int = STATUS_OPEN,
    @ColumnInfo(name = COLUMN_SYNC)         var sync: Boolean = false,
    @Ignore                                 var sheetRow: Int = 0) : Parcelable ...

ТакЯ достиг двух классов: BalanceRoom и PaymentRoom, которые не помечены как сущности

PaymentRoom

@Parcelize
data class PaymentRoom(
    @Embedded private var generalInfo: Payment = Payment(),
    @Embedded private var category: Category = Category(),
    @Relation(parentColumn = Payment.COLUMN_ID, entityColumn = Balance.COLUMN_PAYMENT_ID)
    private var balances: MutableList<Balance> = ArrayList(),
    @Relation(parentColumn = Payment.COLUMN_ID, entityColumn = Attachment.COLUMN_PAYMENT_ID)
    private var attachments: MutableList<Attachment> = ArrayList(),
    @Relation(parentColumn = Payment.COLUMN_ID, entityColumn = PaymentTags.COLUMN_PAYMENT_ID)
    private var tags: MutableList<PaymentTags> = ArrayList() ) : Parcelable{}

BalanceRoom

@Parcelize
data class BalanceRoom(
    @Embedded private var _balance: Balance= Balance(),
    @Embedded private var _account: Account= Account()) : Parcelable {}

Сследующие Daos я могу легко получить PaymentRoom и BalanceRoom, в которых заполнены все поля:

@Dao
abstract class DAO {
@Query("SELECT * FROM " + Payment.TABLE_NAME +
        " INNER JOIN " + Category.TABLE_NAME + " ON " + Category.COLUMN_ID + " = " + Payment.COLUMN_CATEGORY)
internal abstract fun findAllLivePayments(): LiveData<List<PaymentRoom>>

@Query("SELECT * FROM " + Balance.TABLE_NAME +
        " INNER JOIN " + Account.TABLE_NAME + " ON " + Account.COLUMN_ID + " = " + Balance.COLUMN_ACCOUNT_ID)
internal abstract fun findAllLiveBalances(): LiveData<List<BalanceRoom>>

Мой вопрос следующий: можно ли пометить @Relationкласс, который имеет поля с @Embedded? или в этом случае можно ли изменить список Balance на BalanceRoom и каким должен быть запрос для этого?

Из документации я видел, что с @Relation вы можете изменить сущность, поэтому отношение в классе PaymentRoom должнобыть примерно так:

@Relation(entity = Balance::class, parentColumn = Payment.COLUMN_ID, entityColumn = Balance.COLUMN_PAYMENT_ID)
private var balances: MutableList<BalanceRoom> = ArrayList()

Но как должен быть запрос?Я пробовал разные вещи, но kapt не дает полезного вывода, я просто знаю, работает ли запрос или нет

Я знаю, что есть возможные обходные пути, но я бы хотел, чтобы классы были такими простыми, как:возможно, используя kotlin и LiveData, потому что сейчас я получаю список PaymentRoom и цикл по балансам, чтобы найти соответствующие счета, используя идентификаторы, но при таком подходе я не могу заставить LiveData быть в курсе измененийв базе данных.

Спасибо, что уделили время

...