'Query method parameters should either be a type that can be converted into a database column or a List
package com.example.hand.data;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.TypeConverters;
import androidx.room.Update;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Dao
@TypeConverters(dateConverter.class)
public interface salaryDao
{
@Insert
void insertSal(salary sal);
@Update
void updateSal(salary sal);
@Delete
void deleteSal(salary sal);
@Query("select * from salary order by id asc")
LiveData<List<salary>> selectSal(salary...sal);
@Query("select * from salary where time>=:from and time<=:to order by time ")
LiveData<List<salary>> selectByDate(Date from,Date to);
@Query("select * from salary where idCar=:id order by time asc ")
LiveData<List<salary>> selectByDate(Long id);
@Query("select sum(amount) from salary where idCar=:id order by time asc ")
double getSum(long id);
}
the error
C:\Users\MCD\AndroidStudioProjects\Hand\app\src\main\java\com\example\hand\data\salaryDao.java:30: error: Query method parameters should either be a type that can be converted into a database column or a List / Array that contains such type. You can consider adding a Type Adapter for this. LiveData<List> selectSal(salary...sal);
Solution 1:[1]
You have a few issues with:-
@Query("select * from salary order by id asc")
LiveData<List<salary>> selectSal(salary...sal)
The query is saying SELECT every row. It is not saying SELECT some rows according to a parameter. Whilst the function is saying to utilise the passed parameter. Room doesn't know what to do with salary...sal nor would it be able to handle it as it does not equate to something that it can place into the query (a column's value or a list of column values).
So you need to define/use a query that will SELECT certain rows and typically this would be via a WHERE clause.
You appear to want to select a subset of Salaries based upon a list of salary objects. However, a salary, as per the message, is NOT suitable for a query parameter.
I suspect that you want something like:-
@Query("select * from salary WHERE id IN(:salary_id_list) order by id asc")
LiveData<List<Salary>> selectSal(long[] salary_id_list);
So the query is saying SELECT only those rows WHERE the salary's id is in the provided list. The provided list would be something like 10,20,30 (i.e. the id of the respective salaries).
Working Demo
The Salary class @Entity based upon what can be extracted from the code you have provided (so will very likely NOT match your salary class) :-
@Entity
class Salary {
@PrimaryKey
Long id=null;
Date time;
double amount;
long idCar;
/* ADDED for the DEMO*/
public static long[] getSalaryIdList(Salary...salaries) {
long[] rv = new long[salaries.length];
int i = 0;
for (Salary s: salaries) {
rv[i++] = s.id;
}
return rv;
}
}
- Note the added method to extract an array (long[]) of id's from the passed Salaries.
SalaryDao
@Dao
public interface SalaryDao
{
@Insert
long insertSal(Salary sal); //<<<<<<<<<< CHANGED
@Update
void updateSal(Salary sal);
@Delete
void deleteSal(Salary sal);
/*<<<<<<<<<< CHANGED >>>>>>>>>>*/
@Query("select * from salary WHERE id IN(:salary_id_list) order by id asc")
List<Salary> selectSal(long[] salary_id_list);
@Query("select * from salary where time>=:from and time<=:to order by time ")
List<Salary> selectByDate(Date from, Date to);
@Query("select * from salary where idCar=:id order by time asc ")
List<Salary> selectByDate(Long id);
@Query("select sum(amount) from salary where idCar=:id order by time asc ")
double getSum(long id);
}
- Note that for brevity/convenience LiveData has not bee used
The DateConverter class (assumed converter Date to/from long) :-
public class DateConverter {
@TypeConverter
public long fromDateToLong(Date date) {
return date.getTime();
}
@TypeConverter
public Date fromLongToDate(long date) {
return new Date(date);
}
}
- Note @TypeConverters annotation moved to @Database for full scope.
An @Database annotated class, to cater for the demo:-
@TypeConverters({DateConverter.class})
@Database(entities = {Salary.class}, version = 1, exportSchema = false)
abstract class TheDatabase extends RoomDatabase {
abstract SalaryDao getSalaryDao();
private static TheDatabase instance = null;
static TheDatabase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(context,TheDatabase.class,"the_database.db")
.allowMainThreadQueries()
.build();
}
return instance;
}
}
- note allowMainThreadQueries used for brevity/convenience
Finally putting it all together into a demo that adds 5 Salaries and the uses the selectSal
dao method to retrieve a subset of the 5 Salaries (1st,3rd and 5th):-
public class MainActivity extends AppCompatActivity {
TheDatabase db;
SalaryDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = TheDatabase.getInstance(this);
dao = db.getSalaryDao();
Salary s1 = new Salary();
s1.amount = 100;
s1.idCar = 10;
s1.time = new Date();
s1.id = dao.insertSal(s1);
Salary s2 = new Salary();
s2.amount = 200;
s2.idCar = 20;
s2.time = new Date();
s2.id = dao.insertSal(s2);
Salary s3 = new Salary();
s3.amount = 300;
s3.idCar = 30;
s3.time = new Date();
s3.id = dao.insertSal(s3);
Salary s4 = new Salary();
s4.amount = 400;
s4.idCar = 40;
s4.time = new Date();
s4.id = dao.insertSal(s4);
Salary s5 = new Salary();
s5.amount = 500;
s5.idCar = 50;
s5.time = new Date();
s5.id = dao.insertSal(s5);
for(Salary s: dao.selectSal(Salary.getSalaryIdList(s1,s3,s5))) {
Log.d("DBINFO","Salary ID is " + s.id + " Amount is $" + s.amount + " IdCar is " + s.idCar + " Time is " + s.time);
}
}
}
- Note this is intended to just run the once (although will subsequently run but additional rows will be added each time).
The resultant output (for the first run) written to the log :-
2022-05-14 12:55:41.015 D/DBINFO: Salary ID is 1 Amount is $100.0 IdCar is 10 Time is Sat May 14 12:55:40 GMT+10:00 2022
2022-05-14 12:55:41.015 D/DBINFO: Salary ID is 3 Amount is $300.0 IdCar is 30 Time is Sat May 14 12:55:40 GMT+10:00 2022
2022-05-14 12:55:41.015 D/DBINFO: Salary ID is 5 Amount is $500.0 IdCar is 50 Time is Sat May 14 12:55:40 GMT+10:00 2022
- i.e. 1st, 3rd and 5th have been retrieved.
The database via AppInspection :-
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | MikeT |