Room - error incomparable types: int and <null>

Viewed 638

I just started looking at rooms, installing and encountering a bug.

The bug is as follows:

.. \ todolist \ DAO \ NoteDao_Impl.java: 42: error: incomparable types: int and if (value.getId () == null) {

As far as I know, it is because the primary key is int, so this class has an error (this class is of room, not mine created). I do not know how to fix it, please help me.

Some class information

Note.java

@Entity(tableName = "Note")
public class Note {
    @PrimaryKey(autoGenerate = true)
    private Integer id;
    private String content;
    private int color;
    private boolean isChecked;
    private String nameSublist;
    @Ignore
    private Date createAt;

    public Note() {
    }

    public Note(int id, String content) {
        this.id = id;
        this.content = content;
        this.color = 0;
    }
    // getter and setter
}

NoteDao.java

@Dao
public abstract class NoteDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public abstract Long insertNote(Note note);

    @Update(onConflict = OnConflictStrategy.REPLACE)
    public abstract void updateNote(Note note);

    @Delete
    public abstract void deleteNote(Note note);

    @Query("DELETE FROM " + Constants.KEY_TABLE_NAME_NOTE)
    public abstract void deleteAll();

    @Query("DELETE FROM Note WHERE nameSublist= :sublist")
    public abstract void deleteSublist(String sublist);

    @Query("SELECT * FROM Note")
    public abstract List<Note> queryAll();

    @Query("SELECT * FROM Note  WHERE nameSublist = :sublist")
    public abstract List<Note> querySublist(String sublist);

    @Query("SELECT * FROM Note WHERE id = :id")
    public abstract Note queryNote(int id);
}

Appdatabase.java

@Database(entities = {Note.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
    private static final Migration MIGRATION_1_0 = new Migration(1, 0) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            // do something when update version
        }
    };
    private static AppDatabase INSTANCE;

    public static AppDatabase getInstance(Context context) {
        if (INSTANCE == null) {
            INSTANCE = Room.databaseBuilder(context, AppDatabase.class, Constants.KEY_TABLE_NAME_APPDATA) //todolist.sqlite
                    .allowMainThreadQueries()   // allow query in main, default false
                    .addMigrations(MIGRATION_1_0)
                    .fallbackToDestructiveMigration()
                    .build();
        }
        return INSTANCE;
    }

    public abstract NoteDao noteDao();

}

Build.gradle

implementation 'android.arch.persistence.room:runtime:2.2.5'
annotationProcessor 'android.arch.persistence.room:compiler:2.2.5'

image Error bug

2 Answers

Change variable 'Integer id' to 'int id' in Note class and 'Migrate(1, 0)' to 'Migrate(0, 1)' in Appdatabase class i think

I had a similar issue today and the solution may hide particularly well depending on how you built the Entity.

For me the situation arised because at start I cosntructed the Entidy with a primitive id, but later because of some difficulties with generics I decided to change the primary Key field from a long variable to a Long one.

Java aknowledges the casting that needs to be done from Long to long because of their descendancy, so the getters and constructors that stayed as long did not gave me any errors, and I completely forgot about this.

A few days later, when the DB was figured out, Room began giving me the issues that a long cannot be checked to be null, and it happens that the autogenerated code, gets the public methods if the fields are private(ofc).

The simple solution is to place the @NonNull annotation on the field and Room stops checking for its null-ability.

The problem is that even if your @PrimaryKey is set with the @NonNull annotation, Room still abides by what the getters and constructors are saying, and they where saying that the field was a long, not a Long.

So this annotation NEEDS to be placed everywhere, this means the constructor, and getters,.. so everything needs to be changed from long to Long/from primitive to objects,...an easy miss when your entity is big enough and the issue arises days after the changes were made.

@PrimaryKey
@ColumnInfo(name = "id")
@NonNull
private Long id;

public Constructor(
        @NonNull Long id
) {
    this.id = id;
}

@NonNull
public Long getId() {
    return id;
}
Related