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
。如果使用这个然后你得到产品然后问题是流程(这是我怀疑的)。
鉴于我有 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
。如果使用这个然后你得到产品然后问题是流程(这是我怀疑的)。