0

I'm considering using the android Room library as a ORM in my app, but i would like to know more details/comments because of some constraints i have and i was not able to find on the internet (ie.Google;)) When i do the following query:

@Query("SELECT * FROM users")
List<User> getAll();

and if i have thousands off users, wouldn't it be an issue? because from the generated code below it seems to load everything into an ArrayList. Event the LiveData> or Flowable> do the same.

@Override
public List<User> getAll() {
  final String _sql = "SELECT * FROM Users";
  final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
  final Cursor _cursor = __db.query(_statement);
  try {
   final int _cursorId = _cursor.getColumnIndexOrThrow("id");
   final int _cursorName = _cursor.getColumnIndexOrThrow("name");
   final List<User> _result = new ArrayList<User>(_cursor.getCount());
   while(_cursor.moveToNext()) {
     final User _item;
     final String _tmpMId;
     _tmpMId = _cursor.getString(_cursorId);
     final String _tmpMName;
     _tmpMName = _cursor.getString(_cursorName);
     _item = new User(_tmpMId,_tmpMName);
     _result.add(_item);
   }
   return _result;
  } finally {
   _cursor.close();
   _statement.release();
  }
}

@Override
  public Flowable<List<User>> getAllRX() {
    final String _sql = "SELECT * FROM Users";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    return RxRoom.createFlowable(__db, new String[]{"Users"}, new Callable<List<CachedAttendee>>() {
      public List<User> call() throws Exception {
        final Cursor _cursor = __db.query(_statement);
        try {
          final int _cursorId = _cursor.getColumnIndexOrThrow("id");
          final int _cursorName = _cursor.getColumnIndexOrThrow("name");
          final List<User> _result = new ArrayList<User>(_cursor.getCount());
          while(_cursor.moveToNext()) {
            final User _item;
            final String _tmpMId;
            _tmpMId = _cursor.getString(_cursorId);
            final String _tmpMName;
            _tmpMName = _cursor.getBlob(_cursorName);
            _item = new User(_tmpMId,_tmpMName);
            _result.add(_item);
          }
          return _result;
        } finally {
          _cursor.close();
        }
      }

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

Am i looking at it wrongly or Google dismissed this point? I can always use Cursors, but that defeats the point of having an ORM handling that serialisation for me.

Cheers,

Sergio Lima
  • 114
  • 13
  • 2
    But it does what almost all ORM do. Not only the memory is problem ... time needed to create all User instances(in every ORM) bigger than operating with Cursor/DataReader/ResultSet/etc. – Selvin Jun 28 '17 at 14:59
  • ... so for better performance/memory handling using basic access to SQL api is always better choice than ORM ... but of course it may be too abstract(direct access needs more code) ... you cannot have cookie and eat cookie – Selvin Jun 28 '17 at 15:02
  • "cannot have cookie and eat cookie" thats true :).. i know that there's always a catch with any choice one makes, i just wondered if there was a better one, and even if there was some other option/configuration that i could be missing... thanks for the comments – Sergio Lima Jun 28 '17 at 15:19
  • what with this https://developer.android.com/topic/libraries/architecture/paging.html ? – blay Sep 24 '17 at 14:12

1 Answers1

2

and if i have thousands off users, wouldn't it be an issue? because from the generated code below it seems to load everything into an ArrayList.

You asked it to do that. If you do not want a List of all users, do not ask for it. Create a @Query that uses some sort of constraints (e.g., WHERE, LIMIT/OFFSET).

This is not significantly different from other ORM solutions. That being said, if you find some other ORM that you like better, use it. Room is an option, not a requirement.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • first of all, thanks for the comment. I only asked the question because i'm new to this ORM, and was wondering if there was any option/configuration that i was missing or if there was some other option which could be better. The purpose to list all users was just an example, because i wanted to list all users (or any other kind of model) in a recyclerview. I do like the LIMIT/OFFSET suggestion though.. – Sergio Lima Jun 28 '17 at 15:23
  • @SergioLima: Some future update to Room might offer its own approach for handling `LIMIT`/`OFFSET`-based paging, but at the moment it does not have anything for that. Right now, the assumption is that you will be retrieving more focused results (e.g., using search criteria) rather than "everything but the kitchen sink", which might slap you with an `OutOfMemoryError`. – CommonsWare Jun 28 '17 at 15:29