I was developing some simple app, which make use of Room library to create a database to keep info regarding an User model class.
My problem is I'm getting several error when I try to build the database like the following:
error: Entity class must be annotated with @Entity
error: Entities and POJOs must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).
error: An entity must have at least 1 field annotated with @PrimaryKey
error: [SQLITE_ERROR] SQL error or missing database (near ")": syntax error)
error: There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such table: userUi)
Regarding my class are this:
UserDao.java
@Dao
public interface UserDao {
@Insert
void insert(User userUi);
@Query("SELECT DISTINCT id FROM userUi")
List<Byte> getIds();
@Query("SELECT DISTINCT agency_id FROM userUi")
List<String> getAgencyIds();
@Query("SELECT DISTINCT user_id FROM userUi")
List<String> getUserIds();
@Query("SELECT DISTINCT user_code FROM userUi")
List<String> getUserCodes();
@Query("SELECT DISTINCT user_name FROM userUi")
List<String> getUserNames();
@Query("SELECT DISTINCT profile FROM userUi")
List<String> getProfiles();
@Query("SELECT COUNT(*) FROM userUi WHERE agency_id=:agency_id")
Integer getCountByAgencyId(int agency_id);
}
User.java
@Entity(tableName = "userUi", indices = {@Index(value = {"user_code"})})
public class User {
@PrimaryKey(autoGenerate = true)
private String id;
@ColumnInfo(name="agency_id")
private String agency_id;
@ColumnInfo(name="user_id")
private String user_id;
@PrimaryKey(autoGenerate = true)
private String user_code;
@ColumnInfo(name="password")
private String password;
@ColumnInfo(name="csc_authenticable")
private String csc_authenticable;
@ColumnInfo(name="equipment_type")
private String equipment_type;
@ColumnInfo(name = "equipment_subtype")
public String equipment_subtype;
@ColumnInfo(name = "profile")
public String profile;
@ColumnInfo(name = "user_name")
public String user_name;
public User(String id, String agency_id, String user_code, String password, String csc_authenticable, String equipment_type, String equipment_subtype, String profile, String user_name) {
this.id = id;
this.agency_id = agency_id;
this.user_code = user_code;
this.password = password;
this.csc_authenticable = csc_authenticable;
this.equipment_type = equipment_type;
this.equipment_subtype=equipment_subtype;
this.profile = profile;
this.user_name = user_name;
}
public String getId() {
return id;
}
public String getAgency_id() {
return agency_id;
}
public String getUser_id() {
return user_id;
}
public String getUser_code() {
return user_code;
}
public String getPassword() {
return password;
}
public String getCsc_authenticable() {
return csc_authenticable;
}
public String getEquipment_type() {
return equipment_type;
}
public String getEquipment_subtype() {
return equipment_subtype;
}
public String getProfile() {
return profile;
}
public String getUser_name() {
return user_name;
}
public void setId(String id) {
this.id = id;
}
public void setAgency_id(String agency_id) {
this.agency_id = agency_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public void setUser_code(String user_code) {
this.user_code = user_code;
}
public void setPassword(String password) {
this.password = password;
}
public void setCsc_authenticable(String csc_authenticable) {
this.csc_authenticable = csc_authenticable;
}
public void setEquipment_type(String equipment_type) {
this.equipment_type = equipment_type;
}
public void setEquipment_subtype(String equipment_subtype) {
this.equipment_subtype = equipment_subtype;
}
public void setProfile(String profile) {
this.profile = profile;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
}
Database.java
@androidx.room.Database(
entities = {
UserDao.class
},
version = 6
)
@TypeConverters({DateConverter.class})
public abstract class Database extends RoomDatabase {
public static Database buildDataBase(final Context context){
return Room.databaseBuilder(
context,
Database.class,
AppConstant.DB_NAME)
.allowMainThreadQueries().setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
.fallbackToDestructiveMigration().build();
}
public abstract UserDao userUiContractDaoDAO();
}
So, I don't know what it's rising so many errors, but if you can see something I'm missing or doing wrong, take thanks in advance !
Issue 1
The issue causing must be annotated with @Entity is because you are specifying UserDao
as a table in the list of entities. So instead of:-
entities = {
UserDao.class
}
Use :-
entities = {
User.class
}
i.e. the entity not the dao.
Issue 2
The next issue is that you have specified multiple Primary keys, there can only be 1.
error: You cannot have multiple primary keys defined in an Entity. If you want to declare a composite primary key, you should use @Entity#primaryKeys and not use @PrimaryKey. Defined Primary Keys: PrimaryKey[id], PrimaryKey[user_code]
So perhaps :-
//@PrimaryKey(autoGenerate = true) /*,<<<<<<<< COMMENTED OUT can't have 2 primary keys*/
private String user_code;
Issue 3
You will then get
error: If a primary key is annotated with autoGenerate, its type must be int, Integer, long or Long.
So perhaps;-
@PrimaryKey/*(autoGenerate = true)*/
private String id;
Issue 4
Then :-
error: You must annotate primary keys with @NonNull. "id" is nullable. SQLite considers this a bug and Room does not allow it. See SQLite docs for details: https://www.sqlite.org/lang_createtable.html
private String id;
:-
@NonNull
@PrimaryKey/*(autoGenerate = true)*/
private String id;
Issue 5
Next you will get:-
Entities and POJOs must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).
This is because none of the constructors handles the expectation of building a Byte from a String as per:-
@Query("SELECT DISTINCT id FROM userUi")
List<Byte> getIds();
Use :-
@Query("SELECT DISTINCT id FROM userUi")
List<String> getIds();
And then the project will compile successfully.
If you want user_code to be unique then you can use:-
@Entity(tableName = "userUi", indices = {@Index(value = {"user_code"}, unique = true)})