I have entity class Person
and I want to query persons from database by feature
which may or may not be null. When I set feature to non-null the query works but when the feature is null the query returns empty list. What I am doing wrong?
TEST
Context context = InstrumentationRegistry.getContext();
AppDb db = Room.inMemoryDatabaseBuilder(context, AppDb.class).allowMainThreadQueries().build();
PersonDao dao = db.personDao();
dao.insert(new Person("El Risitas", "Funny"));
dao.insert(new Person("Elon Musk", "Alien"));
dao.insert(new Person("Donald Trump", null));
assertEquals(3, dao.getAll().size());
assertEquals("Funny", dao.getByFeature("Funny").get(0).getFeature());
// fails because dao.getByFeature(null) = EMPTY LIST
assertEquals(null, dao.getByFeature(null).get(0).getFeature());
Person.java
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "person")
public class Person {
@ColumnInfo(name = "id") @PrimaryKey(autoGenerate = true) private int id;
@ColumnInfo(name = "name") private String name;
@ColumnInfo(name = "feature") private String feature;
public Person(String name, String feature) {
this.name = name;
this.feature = feature;
}
public void setId(int id) { this.id = id; }
public int getId() { return id; }
public String getName() { return name; }
public String getFeature() { return feature; }
}
PersonDao.java
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import java.util.List;
@Dao
public interface PersonDao {
@Insert
void insert(Person person);
@Query("SELECT * FROM person")
List<Person> getAll();
@Query("SELECT * FROM person WHERE feature = :feature")
List<Person> getByFeature(String feature);
}
AppDb.java
import androidx.room.Database;
import androidx.room.RoomDatabase;
@Database(
version = 1,
exportSchema = false,
entities = {Person.class}
)
public abstract class AppDb extends RoomDatabase {
public abstract PersonDao personDao();
}
Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. Room is now considered as a better approach for data persistence than SQLiteDatabase.
When you use the Room persistence library to store your app's data, you interact with the stored data by defining data access objects, or DAOs. Each DAO includes methods that offer abstract access to your app's database. At compile time, Room automatically generates implementations of the DAOs that you define.
Room is a persistent library that is part of the Android jetpack. It is built on top of SQLite.
3.1 Add the Clear all data menu optionIn the Options menu, select Clear all data. All words should disappear. Restart the app. (Restart it from your device or the emulator; don't run it again from Android Studio) You should see the initial set of words.
In SQL, nothing is ever equal to null. (Nothing is ever not equal to null, either.) You have to use is null
. So your query could be something like (untested)
SELECT * FROM person WHERE feature = :feature or (feature is null and :feature is null)
You can also use IS
operator instead of =
.
SELECT * FROM person WHERE feature IS :feature
From SQLite documentation:
The IS and IS NOT operators work like = and != except when one or both of the operands are NULL. In this case, if both operands are NULL, then the IS operator evaluates to 1 (true) and the IS NOT operator evaluates to 0 (false). If one operand is NULL and the other is not, then the IS operator evaluates to 0 (false) and the IS NOT operator is 1 (true). It is not possible for an IS or IS NOT expression to evaluate to NULL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With