Home > Enterprise >  What happens if no records exists when I use Room to query?
What happens if no records exists when I use Room to query?

Time:03-29

I use Room in my Android Studio App, the Code A will crash when no record exists to query

What happens if no records exists when I use Room to query with Code B ?

@Dao
interface  RecordDao {

   // Code A
   @Query("SELECT * FROM record_table where id=:id")
   fun getByID(id:Int): Flow<RecordEntity>


   // Code B
   @Query("SELECT * FROM record_table")
   fun getAll(): Flow<List<RecordEntity>>

}

CodePudding user response:

If you look at the code generated by room for the RecordDao_Impl class implementation of RecordDao, you'll notice multiple things:

  1. The getById function code returns null when no matching records exist in the table, and since your 'Code A' function return type is not null, kotlin throws a NullPointerException for the first function.
  2. The getAll function code returns a Flow object with an ArrayList, in case it found any records then it adds them to the list, otherwise it just emits the empty ArrayList to the Flow object, therefore, you'll always get a flow object with a list inside it regardless if room found matching records or not, so no exception is thrown.

You can understand this a bit more if you look at the code generated for the two functions here:

@Override
public Flow<RecordEntity> getByID(final int id) {
    final String _sql = "SELECT * FROM record_table where id=?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    _statement.bindLong(_argIndex, id);
    return CoroutinesRoom.createFlow(__db, false, new String[]{"record_table"}, new Callable<RecordEntity>() {
        @Override
        public RecordEntity call() throws Exception {
            final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
            try {
                final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "id");
                final RecordEntity _result;
                if (_cursor.moveToFirst()) {
                    final int _tmpId;
                    _tmpId = _cursor.getInt(_cursorIndexOfId);
                    _result = new RecordEntity(_tmpId);
                } else {
                    _result = null;
                }
                return _result;
            } finally {
                _cursor.close();
            }
        }

        @Override
        protected void finalize() {
            _statement.release();
        }
    });
}

@Override
public Flow<List<RecordEntity>> getAll() {
    final String _sql = "SELECT * FROM record_table";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    return CoroutinesRoom.createFlow(__db, false, new String[]{"record_table"}, new Callable<List<RecordEntity>>() {
        @Override
        public List<RecordEntity> call() throws Exception {
            final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
            try {
                final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "id");
                final List<RecordEntity> _result = new ArrayList<RecordEntity>(_cursor.getCount());
                while (_cursor.moveToNext()) {
                    final RecordEntity _item;
                    final int _tmpId;
                    _tmpId = _cursor.getInt(_cursorIndexOfId);
                    _item = new RecordEntity(_tmpId);
                    _result.add(_item);
                }
                return _result;
            } finally {
                _cursor.close();
            }
        }

        @Override
        protected void finalize() {
            _statement.release();
        }
    });
}
  • Related