5
votes

I keep a list of products in 'Order'. When I try to get a list of products from the Room. I get the following error. But I made a TypeConvertor. What could be the error?

Order

   @Entity(tableName = Order.TABLE_NAME)
@JsonClass(generateAdapter = true)
data class Order(
    @PrimaryKey(autoGenerate = true)
    val id: Long,
    val isSendCheque: Int,
    val phone: String,
    val name: String,
    val comment: String? = "",
    val timeFrom: String,
    val timeTo: String,
    @TypeConverters(Converters::class)
    @ColumnInfo(name = "listProduct")
    var listProduct: List<Product>? = null,
    val publicOrderId: String
) {
    companion object {
        const val TABLE_NAME = "mau_order"
    }
}

Product

@Parcelize
@JsonClass(generateAdapter = true)
data class Product(
        @SerializedName("id")
        @PrimaryKey
        var id: Long = -1,
        @SerializedName("order_id") var orderId: Long = -1,
        @SerializedName("name") var name: String = "name product",
        @SerializedName("packaging") var packaging: String? = "1 кг",
        @SerializedName("path_image") var pathImage: String = "",
        @SerializedName("price") var price: Double = 0.0,
        @SerializedName("price_discount") var priceDiscount: Double = 0.0,
        @SerializedName("product_id") var productId: Int = -1,
        @SerializedName("quantity") var quantity: Double = 0.0,
        @SerializedName("units") var units: String = "ШТ",
        @SerializedName("created_at") var createdAt: String = "",
        @SerializedName("updated_at") var updatedAt: String = "",
        @SerializedName("brgew") var brgew: String = "",
        @SerializedName("gewei") var gewei: String = "кг"
) : Parcelable

OrdersDao

   @Dao
interface OrdersDao {
    /**
     * Inserts [orders] into the [Order.TABLE_NAME] table.
     * Duplicate values are replaced in the table.
     * @param orders Orders
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertOrders(orders: List<Order>)
    /**
     * Inserts [orders] into the [Order.TABLE_NAME] table.
     * Duplicate values are replaced in the table.
     * @param orders Orders
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertOrders(order: Order)

    /**
     * Deletes all the orders from the [Order.TABLE_NAME] table.
     */
    @Query("DELETE FROM ${Order.TABLE_NAME}")
    suspend fun deleteAllOrders()

    /**
     * Fetches the order from the [Order.TABLE_NAME] table whose id is [orderId].
     * @param orderId Unique ID of [Order]
     * @return [Flow] of [Order] from database table.
     */
    @Query("SELECT * FROM ${Order.TABLE_NAME} WHERE ID = :orderId")
    fun getOrderById(orderId: Long): LiveData<Order>

    //ERROR
    @Query("SELECT listProduct FROM ${Order.TABLE_NAME} WHERE ID = :orderId")
    fun getBasketById(orderId: Long): LiveData<Order>

    /**
     * Fetches all the orders from the [Order.TABLE_NAME] table.
     * @return [Flow]
     */
    @Query("SELECT * FROM ${Order.TABLE_NAME}")
    fun getAllOrders(): LiveData<List<Order>>
}

Converters

 @TypeConverter
fun stringToProductList(data: String?): MutableList<Product> {
    if (data == null) {
        return Collections.emptyList()
    }

    val listType = object : TypeToken<MutableList<Product>>() {

    }.type

    return gson.fromJson(data, listType)
}

@TypeConverter
fun ProductListToString(someObjects: MutableList<Product>?): String? {
    if (someObjects == null) {
        return null
    }
    return gson.toJson(someObjects)
}

Error

OrdersDao.java:53: error: The columns returned by the query does not have the fields [id,orderId,name,pathImage,price,priceDiscount,productId,quantity,units,createdAt,updatedAt,brgew,gewei] in com.vepe.navigation.model.entity.Product even though they are annotated as non-null or primitive. Columns returned by the query: [listProduct] public abstract java.util.List<com.vepe.navigation.model.entity.Product> getBasketHistoryFromOrderById(long orderId); Current JDK version 1.8.0_272-b10 has a bug (https://bugs.openjdk.java.net/browse/JDK-8007720) that prevents Room from being incremental. Consider using JDK 11+ or the embedded JDK shipped with Android Studio 3.5+.C:\Users\mind\StudioProjects\Sarah_navigationProject\ProjectAndroid\app\build\tmp\kapt3\stubs\debug\com\vepe\navigation\model\entity\Product.java:8: error: Entity class must be annotated with @Entity

Help me please ! Thanks

UPDATE I tried to put the @Entity annotation I do not know whether they are necessary or not in my case And got the following error

error: The columns returned by the query does not have the fields [id,orderId,name,pathImage,price,priceDiscount,productId,quantity,units,createdAt,updatedAt,brgew,gewei] in com.vepe.navigation.model.entity.Product even though they are annotated as non-null or primitive. Columns returned by the query: [listProduct] public abstract kotlinx.coroutines.flow.Flow<java.util.List<com.vepe.navigation.model.entity.Product>> getBasketHistoryFromOrderById(long orderId); Current JDK version 1.8.0_272-b10 has a bug (https://bugs.openjdk.java.net/browse/JDK-8007720) that prevents Room from being incremental. Consider using JDK 11+ or the embedded JDK shipped with Android Studio 3.5+.C:\Users\mind\StudioProjects\Sarah_navigationProject\ProjectAndroid\app\build\tmp\kapt3\stubs\debug\com\vepe\navigation\data\local\dao\OrdersDao.java:53: warning: The query returns some columns [listProduct] which are not used by com.vepe.navigation.model.entity.Product. You can use @ColumnInfo annotation on the fields to specify the mapping. com.vepe.navigation.model.entity.Product has some fields [id, orderId, name, packaging, pathImage, price, priceDiscount, productId, quantity, units, createdAt, updatedAt, brgew, gewei] which are not returned by the query. If they are not supposed to be read from the result, you can mark them with @Ignore annotation. You can suppress this warning by annotating the method with @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH). Columns returned by the query: listProduct. Fields in com.vepe.navigation.model.entity.Product: id, orderId, name, packaging, pathImage, price, priceDiscount, productId, quantity, units, createdAt, updatedAt, brgew, gewei.

3
Have you tried making all the columns in your Product class nullable?DCruz22
@DCruz22 yes, i tried and i have this error error: Not sure how to convert a Cursor to this method's return type (ru.gkomega.maumarket.model.entity.Product). and below If they are not supposed to be read from the result, you can mark them with @Ignore annotation. You can suppress this warning by annotating the method with @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH). Columns returned by the query: listProduct.WBLord

3 Answers

1
votes

You need to fix this query:

@Query("SELECT listProduct FROM ${Order.TABLE_NAME} WHERE ID = :orderId")
    fun getBasketById(orderId: Long): LiveData<Order>

The problem is mismatch between selected field (listProduct) and returned type (Order). Room complains it can't understand how to build Order instance having just one its field - listProduct.

The simplest way to fix it would be to select all fields needed for creating Order instance:

@Query("SELECT * FROM ${Order.TABLE_NAME} WHERE ID = :orderId")
    fun getBasketById(orderId: Long): LiveData<Order>
1
votes

I came up with this way to solve the problem

In OrderService

@GET("orders/baskethistory/id/{id}")
suspend fun getBasketHistoryById(@Path("id") id: Long): Response<BasketHistory>

Data class for list of object

data class BasketHistory(
    @SerializedName("basketHistory") val listProduct : MutableList<Product>
)

Dao

@Query("SELECT id,listProduct FROM ${Order.TABLE_NAME} WHERE ID = :orderId")
fun getBasketById(orderId: Long): LiveData<BasketHistory>

Try it

0
votes

It is straight forward, some times with a lot many queries and data classes we miss out on what we need and what we write in code.

 //ERROR
    @Query("SELECT listProduct FROM ${Order.TABLE_NAME} WHERE ID = :orderId")
    fun getBasketById(orderId: Long): LiveData<Order>

You are returning Order LiveData in the above query, but asking for listProduct which is incorrect, either

  • Make it '*'(To get the list of orders/single order)

    @Query("SELECT * FROM ${Order.TABLE_NAME} WHERE ID = :orderId") fun getBasketById(orderId: Long): LiveData<Order>

  • Or change the return value to LiveData<List< Product>>

    @Query("SELECT listProduct FROM ${Order.TABLE_NAME} WHERE ID = :orderId") fun getBasketById(orderId: Long): LiveData<List<Product>>

This will solve your problem.

In addition to this am adding Room Conversions as well,

object RoomConverters {

     @TypeConverter
        @JvmStatic
        fun restoreModelList(listOfString: String): List<RoomModelList> {
            return Gson().fromJson(listOfString, object : TypeToken<List<RoomModelList>>() {
            }.type)
        }
    
        @TypeConverter
        @JvmStatic
        fun saveModelListAsString(listOfString: List<RoomModel>): String {
            return Gson().toJson(listOfString)
        }

}