Room 数据库中的嵌套关​​系返回空数据 Android

Null Data Returned with Nested Relation in Room Database Android

鉴于我有 3 个实体,Order 包含 LineItem 的列表,每个 LineItem 将通过 [= 与一个 Product 相关联37=]productId.

当我从 OrderDao 获取数据时,product 字段的 returns 为空,但在 lineItem 字段中,它有数据。虽然我可以使用 ProductWithLineItem 获取数据。 已经尝试了很多解决方法,但它不起作用。 这是我的实体和 dao

代码

实体

@Entity(tableName = DataConstant.ORDER_TABLE)
data class Order(
    @PrimaryKey
    @ColumnInfo(name = "orderId")
    val id: String,

    @ColumnInfo(name = "status")
    var status: String
)
@Entity(tableName = DataConstant.LINE_ITEM_TABLE)
data class LineItem(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "lineItemId")
    val id: Long,

    @ColumnInfo(name = "productId")
    val productId: String,

    @ColumnInfo(name = "orderId")
    val orderId: String,

    @ColumnInfo(name = "quantity")
    var quantity: Int,

    @ColumnInfo(name = "subtotal")
    var subtotal: Double
) 

@Entity(tableName = DataConstant.PRODUCT_TABLE)
data class Product(
    @PrimaryKey
    @NonNull
    @ColumnInfo(name = "productId")
    val id: String,

    @ColumnInfo(name = "name")
    var name: String?,

    @ColumnInfo(name = "description")
    var description: String?,

    @ColumnInfo(name = "price")
    var price: Double?,

    @ColumnInfo(name = "image")
    var image: String?,

    )

关系 POJO

data class ProductAndLineItem(
    @Embedded val lineItem: LineItem?,
    @Relation(
        parentColumn = "productId",
        entityColumn = "productId"
    )
    val product: Product?
)

data class OrderWithLineItems(
    @Embedded var order: Order,
    @Relation(
        parentColumn = "orderId",
        entityColumn = "orderId",
        entity = LineItem::class
    )
    val lineItemList: List<ProductAndLineItem>
)


@Dao
interface OrderDao {
    @Transaction
    @Query("SELECT * FROM `${DataConstant.ORDER_TABLE}` WHERE orderId = :id")
    fun getById(id: String): Flow<OrderWithLineItems>
}

运行道

后的结果

Result after running query

Here is my code for entities and dao

你的代码看起来没问题,除了返回 Flow、测试、使用你的代码,但在主线程上使用 List(没有 WHERE 子句),即 Dao 是:-

@Query("SELECT * FROM ${DataConstant.ORDER_TABLE}")
@Transaction
abstract fun getOrderWithLineItemsAndWithProduct(): List<OrderWithLineItems>

结果:-

数据正在 loaded/tested 使用 :-

    db = TheDatabase.getInstance(this)
    orderDao = db.getOrderDao()
    orderDao.clearAll()

    orderDao.insert(Product("product1","P1","desc1",10.01,"image1"))
    orderDao.insert(Product("product2","P2","desc2",10.02,"image2"))
    orderDao.insert(Product("product3","P3","desc3",10.03,"image3"))
    orderDao.insert(Product("product4","P4","desc4",10.04,"image4"))
    orderDao.insert(Product("","","",0.0,""))

    val o1 = orderDao.insert(Order("Order1","initiaited"))
    val o2 = orderDao.insert(Order("Order2","finalised")) // Empty aka no List Items

    val o1l1 = orderDao.insert(LineItem(10,"product3","Order1",1,10.01))
    val o1l2 = orderDao.insert(LineItem(20,"product4","Order1",2,20.08))
    val o1l3 = orderDao.insert(LineItem(30,"","Order1",3,30.09))
    val o1l4 = orderDao.insert(LineItem(40,"","x",1,10.01))
    //val o1l3 = orderDao.insert(LineItem(30,"no such product id","Order1",10,0.0))
    // exception whilst trying to extract if not commented out at test = ....
    val TAG = "ORDERINFO"
    val test = orderDao.getOrderWithLineItemsAndWithProduct()

    for(owl: OrderWithLineItems in orderDao.getOrderWithLineItemsAndWithProduct()) {
        Log.d(TAG,"Order is ${owl.order.id} status is ${owl.order.status}")
        for(pal: ProductAndLineItem in owl.lineItemList) {
            Log.d(TAG,"\tLine Item is ${pal.lineItem.id} " +
                    "for Order ${pal.lineItem.orderId} " +
                    "for ProductID ${pal.lineItem.productId} " +
                    "Quantity=${pal.lineItem.quantity} " +
                    "Product description is ${pal.product.description} Product Image is ${pal.product.image} Price is ${pal.product.price}")
        }
    }

因此,我认为问题可能是出于某种原因,Flow 正在检测第一个查询何时完成但先于基础查询。

也就是说,当使用@Relation 时,核心对象(订单)通过查询提取,然后创建核心对象,然后通过另一个查询提取相关对象,并用于将所有相关对象构建为列表(除非只是当它不必是列表时的那个)。因此,在此基础查询之前,核心对象的基础对象将具有 null 或空列表。当然,使用 @Relations 的层次结构,然后将其复制 along/down 层次结构。

我建议暂时将 .allowMainThreadQueires 添加到 databaseBuilder 并使用 List<OrderWithLineItems> 或仅使用一个 OrderWithLineItems。如果使用这个然后你得到产品然后问题是流程(这是我怀疑的)。