title: Rxjava2 just method - how to run room insertion on another thread?
body: <p>I have a room persistant database insertion method which looks like this:</p>
  
  <pre><code>@Dao
  public interface CountriesDao{
  
      @Insert(onConflict = REPLACE)
      List&lt;Long&gt; addCountries(List&lt;CountryModel&gt; countryModel);
  }
  </code></pre>
  
  <p>I realize that this can't be run on the main thread. Here is how I define my database:</p>
  
  <pre><code>Room.inMemoryDatabaseBuilder(context.getApplicationContext(), MyDatabase.class).build();
  </code></pre>
  
  <p>I am trying to use rxjava2 so that I don't run on main thread. I have created the following method:</p>
  
  <pre><code>public void storeCountries(List&lt;CountryModel&gt; countriesList) {
          Observable.just(db.countriesDao().addCountries(countriesList))
                  .subscribeOn(Schedulers.io())
                  .observeOn(AndroidSchedulers.mainThread())
                  .subscribe(new DefaultSubscriber&lt;List&lt;Long&gt;&gt;(){
              @Override
              public void onSubscribe(@NonNull Disposable d) {
                  super.onSubscribe(d);
              }
  
              @Override
              public void onNext(@NonNull List&lt;Long&gt; longs) {
                  super.onNext(longs);
                  Timber.d("insert countries transaction complete");
              }
  
              @Override
              public void onError(@NonNull Throwable e) {
                  super.onError(e);
                  Timber.d("error storing countries in db"+e);
              }
  
              @Override
              public void onComplete() {
                  Timber.d("insert countries transaction complete");
              }
          });
      }
  </code></pre>
  
  <p>For me this is clearly now running on another thread. NOT the main thread but when I run this code i get the following error:</p>
  
  <p>The full stack trace is below. Why is this happening ?</p>
  
  <blockquote>
    <p>Process: com.mobile.myapp.staging, PID: 12990<br>
    java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.
    Caused by: java.lang.IllegalStateException: Cannot access database on
    the main thread since it may potentially lock the UI for a long period
    of time.
                                                                                       at
    io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:111)
                                                                                       at android.os.Handler.handleCallback(Handler.java:751)
                                                                                       at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                       at android.os.Looper.loop(Looper.java:154)
                                                                                       at android.app.ActivityThread.main(ActivityThread.java:6077)
                                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                                       at
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
                                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
                                                                                    Caused by: java.lang.IllegalStateException: Cannot access database on
    the main thread since it may potentially lock the UI for a long period
    of time.
                                                                                       at
    android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:138)
                                                                                       at
    android.arch.persistence.room.RoomDatabase.beginTransaction(RoomDatabase.java:185)
                                                                                       at
    com.mobile.myapp.data.room.dao.CountriesDao_Impl.addCountries(CountriesDao_Impl.java:165)
                                                                                       at
    com.mobile.myapp.data.repositories.CountryRepository.storeCountries(CountryRepository.java:42)
                                                                                       at
    com.mobile.myapp.UI.mvp.Presenters.SignUpPresenter.cacheCountries(SignUpPresenter.java:40)
                                                                                       at
    com.mobile.myapp.UI.mvp.Presenters.SignUpPresenter$CountriesSubscriber.onNext(SignUpPresenter.java:60)
                                                                                       at
    com.mobile.myapp.UI.mvp.Presenters.SignUpPresenter$CountriesSubscriber.onNext(SignUpPresenter.java:49)
                                                                                       at
    io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:200)
                                                                                       at
    io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
                                                                                       at
    io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109)
                                                                                       at android.os.Handler.handleCallback(Handler.java:751) 
                                                                                       at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                       at android.os.Looper.loop(Looper.java:154) 
                                                                                       at android.app.ActivityThread.main(ActivityThread.java:6077) 
                                                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                                                       at
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
                                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)</p>
  </blockquote>
  
  <p>Not important but if you need to know what defaultSubscriber class looks like here it is:</p>
  
  <p><strong>DefaultSubscriber.java</strong></p>
  
  <pre><code>public class DefaultSubscriber&lt;T&gt; implements Observer&lt;T&gt; {
  
  Disposable disposable;
  
  @Override
  public void onSubscribe(@NonNull Disposable d) {
      disposable = d;
  }
  
  @Override
  public void onNext(@NonNull T t) {
  
  }
  
  @Override
  public void onError(@NonNull Throwable e) {
      Timber.e(e);
  }
  
  @Override
  public void onComplete() {
  
  }
  
  public void unsubscribe(){
      if(disposable!=null &amp;&amp; !disposable.isDisposed()){
          disposable.dispose();
      }
    }
  }
  </code></pre>