Skip to content
Advertisement

error: Not sure how to handle insert method’s return type

So I’m trying to use Executor execute the Dao’s in my android app, but when I created the Executor, it said it required the method being run to have a Runnable return type?

So I made them all return Runnable, but now Android Studio gives me the error:

/database/TripDao.java:28: error: Not sure how to handle insert method's return type.
    Runnable insertTrip(Trip trip);
             ^

Dao:

import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;
import java.util.UUID;

@Dao
public interface TripDao {
    @Query("DELETE FROM trip")
    public void deleteTrips();

    @Query("SELECT * FROM trip")
    LiveData<List<Trip>> getAll();

    @Query("SELECT * FROM trip WHERE uuid=:id")
    public LiveData<Trip> getTrip(UUID id);

    @Delete
    Runnable delete(Trip trip);

    @Insert
    Runnable insertTrip(Trip trip);

    @Update
    Runnable updateTrip(Trip trip);


}

Repository:

package com.example.csc202assignment.database;

import android.content.Context;

import androidx.lifecycle.LiveData;
import androidx.room.Room;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;


public class TripRepository {
    private static TripRepository INSTANCE = null;
    private final String DATABASE_NAME = "trip-database";
    private Context context;
    TripDatabase database;
    static TripDao tripDao;
    Executor executor = Executors.newSingleThreadExecutor();

    private TripRepository(Context context) {
        this.context = context;
        this.database = Room.databaseBuilder(
                context.getApplicationContext(),
                TripDatabase.class,DATABASE_NAME).build();
         tripDao = database.tripDao();

    }

    void deleteTrips(){
        tripDao.deleteTrips();
    }

    void delete(Trip trip){
        executor.execute(tripDao.delete(trip));

    }

    void insertTrip(Trip trip){
        executor.execute(tripDao.insertTrip(trip));
    }

    void updateTrip(Trip trip){
        executor.execute(tripDao.updateTrip(trip));
    }

    public LiveData<List<Trip>> getAll(){ return tripDao.getAll();
    }

    public static LiveData<Trip> getTrip(UUID id){
        return tripDao.getTrip(id);
    }

    public static void initialise(Context context){
        if(INSTANCE==null){
            INSTANCE = new TripRepository(context);
        }
    }

     public static TripRepository get() throws IllegalStateException {
         try {
             return INSTANCE;
         } catch (IllegalStateException e) {
             System.out.println("TripRepository must be initialised");
         }
         return INSTANCE;
     }
}

Dao_Impl

package com.example.csc202assignment.database;

import android.database.Cursor;
import androidx.lifecycle.LiveData;
import androidx.room.EntityDeletionOrUpdateAdapter;
import androidx.room.EntityInsertionAdapter;
import androidx.room.RoomDatabase;
import androidx.room.RoomSQLiteQuery;
import androidx.room.SharedSQLiteStatement;
import androidx.room.util.CursorUtil;
import androidx.room.util.DBUtil;
import androidx.sqlite.db.SupportSQLiteStatement;
import java.lang.Class;
import java.lang.Exception;
import java.lang.Override;
import java.lang.Runnable;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;

@SuppressWarnings({"unchecked", "deprecation"})
public final class TripDao_Impl implements TripDao {
  private final RoomDatabase __db;

  private final EntityInsertionAdapter<Trip> __insertionAdapterOfTrip;

  private final TripTypeConverter __tripTypeConverter = new TripTypeConverter();

  private final EntityDeletionOrUpdateAdapter<Trip> __deletionAdapterOfTrip;

  private final EntityDeletionOrUpdateAdapter<Trip> __updateAdapterOfTrip;

  private final SharedSQLiteStatement __preparedStmtOfDeleteTrips;

  public TripDao_Impl(RoomDatabase __db) {
    this.__db = __db;
    this.__insertionAdapterOfTrip = new EntityInsertionAdapter<Trip>(__db) {
      @Override
      public String createQuery() {
        return "INSERT OR ABORT INTO `Trip` (`uuid`,`title`,`destination`,`date`,`duration`) VALUES (?,?,?,?,?)";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, Trip value) {
        final String _tmp;
        _tmp = __tripTypeConverter.fromUUID(value.uuid);
        if (_tmp == null) {
          stmt.bindNull(1);
        } else {
          stmt.bindString(1, _tmp);
        }
        if (value.title == null) {
          stmt.bindNull(2);
        } else {
          stmt.bindString(2, value.title);
        }
        if (value.destination == null) {
          stmt.bindNull(3);
        } else {
          stmt.bindString(3, value.destination);
        }
        if (value.date == null) {
          stmt.bindNull(4);
        } else {
          stmt.bindString(4, value.date);
        }
        if (value.duration == null) {
          stmt.bindNull(5);
        } else {
          stmt.bindString(5, value.duration);
        }
      }
    };
    this.__deletionAdapterOfTrip = new EntityDeletionOrUpdateAdapter<Trip>(__db) {
      @Override
      public String createQuery() {
        return "DELETE FROM `Trip` WHERE `uuid` = ?";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, Trip value) {
        final String _tmp;
        _tmp = __tripTypeConverter.fromUUID(value.uuid);
        if (_tmp == null) {
          stmt.bindNull(1);
        } else {
          stmt.bindString(1, _tmp);
        }
      }
    };
    this.__updateAdapterOfTrip = new EntityDeletionOrUpdateAdapter<Trip>(__db) {
      @Override
      public String createQuery() {
        return "UPDATE OR ABORT `Trip` SET `uuid` = ?,`title` = ?,`destination` = ?,`date` = ?,`duration` = ? WHERE `uuid` = ?";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, Trip value) {
        final String _tmp;
        _tmp = __tripTypeConverter.fromUUID(value.uuid);
        if (_tmp == null) {
          stmt.bindNull(1);
        } else {
          stmt.bindString(1, _tmp);
        }
        if (value.title == null) {
          stmt.bindNull(2);
        } else {
          stmt.bindString(2, value.title);
        }
        if (value.destination == null) {
          stmt.bindNull(3);
        } else {
          stmt.bindString(3, value.destination);
        }
        if (value.date == null) {
          stmt.bindNull(4);
        } else {
          stmt.bindString(4, value.date);
        }
        if (value.duration == null) {
          stmt.bindNull(5);
        } else {
          stmt.bindString(5, value.duration);
        }
        final String _tmp_1;
        _tmp_1 = __tripTypeConverter.fromUUID(value.uuid);
        if (_tmp_1 == null) {
          stmt.bindNull(6);
        } else {
          stmt.bindString(6, _tmp_1);
        }
      }
    };
    this.__preparedStmtOfDeleteTrips = new SharedSQLiteStatement(__db) {
      @Override
      public String createQuery() {
        final String _query = "DELETE FROM trip";
        return _query;
      }
    };
  }

  @Override
  public Runnable insertTrip(final Trip trip) {
    __db.assertNotSuspendingTransaction();
  }

  @Override
  public Runnable delete(final Trip trip) {
    __db.assertNotSuspendingTransaction();
  }

  @Override
  public Runnable updateTrip(final Trip trip) {
    __db.assertNotSuspendingTransaction();
  }

  @Override
  public void deleteTrips() {
    __db.assertNotSuspendingTransaction();
    final SupportSQLiteStatement _stmt = __preparedStmtOfDeleteTrips.acquire();
    __db.beginTransaction();
    try {
      _stmt.executeUpdateDelete();
      __db.setTransactionSuccessful();
    } finally {
      __db.endTransaction();
      __preparedStmtOfDeleteTrips.release(_stmt);
    }
  }

  @Override
  public LiveData<List<Trip>> getAll() {
    final String _sql = "SELECT * FROM trip";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    return __db.getInvalidationTracker().createLiveData(new String[]{"trip"}, false, new Callable<List<Trip>>() {
      @Override
      public List<Trip> call() throws Exception {
        final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
        try {
          final int _cursorIndexOfUuid = CursorUtil.getColumnIndexOrThrow(_cursor, "uuid");
          final int _cursorIndexOfTitle = CursorUtil.getColumnIndexOrThrow(_cursor, "title");
          final int _cursorIndexOfDestination = CursorUtil.getColumnIndexOrThrow(_cursor, "destination");
          final int _cursorIndexOfDate = CursorUtil.getColumnIndexOrThrow(_cursor, "date");
          final int _cursorIndexOfDuration = CursorUtil.getColumnIndexOrThrow(_cursor, "duration");
          final List<Trip> _result = new ArrayList<Trip>(_cursor.getCount());
          while(_cursor.moveToNext()) {
            final Trip _item;
            _item = new Trip();
            final String _tmp;
            if (_cursor.isNull(_cursorIndexOfUuid)) {
              _tmp = null;
            } else {
              _tmp = _cursor.getString(_cursorIndexOfUuid);
            }
            _item.uuid = __tripTypeConverter.toUUID(_tmp);
            if (_cursor.isNull(_cursorIndexOfTitle)) {
              _item.title = null;
            } else {
              _item.title = _cursor.getString(_cursorIndexOfTitle);
            }
            if (_cursor.isNull(_cursorIndexOfDestination)) {
              _item.destination = null;
            } else {
              _item.destination = _cursor.getString(_cursorIndexOfDestination);
            }
            if (_cursor.isNull(_cursorIndexOfDate)) {
              _item.date = null;
            } else {
              _item.date = _cursor.getString(_cursorIndexOfDate);
            }
            if (_cursor.isNull(_cursorIndexOfDuration)) {
              _item.duration = null;
            } else {
              _item.duration = _cursor.getString(_cursorIndexOfDuration);
            }
            _result.add(_item);
          }
          return _result;
        } finally {
          _cursor.close();
        }
      }

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

  @Override
  public LiveData<Trip> getTrip(final UUID id) {
    final String _sql = "SELECT * FROM trip WHERE uuid=?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    final String _tmp;
    _tmp = __tripTypeConverter.fromUUID(id);
    if (_tmp == null) {
      _statement.bindNull(_argIndex);
    } else {
      _statement.bindString(_argIndex, _tmp);
    }
    return __db.getInvalidationTracker().createLiveData(new String[]{"trip"}, false, new Callable<Trip>() {
      @Override
      public Trip call() throws Exception {
        final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
        try {
          final int _cursorIndexOfUuid = CursorUtil.getColumnIndexOrThrow(_cursor, "uuid");
          final int _cursorIndexOfTitle = CursorUtil.getColumnIndexOrThrow(_cursor, "title");
          final int _cursorIndexOfDestination = CursorUtil.getColumnIndexOrThrow(_cursor, "destination");
          final int _cursorIndexOfDate = CursorUtil.getColumnIndexOrThrow(_cursor, "date");
          final int _cursorIndexOfDuration = CursorUtil.getColumnIndexOrThrow(_cursor, "duration");
          final Trip _result;
          if(_cursor.moveToFirst()) {
            _result = new Trip();
            final String _tmp_1;
            if (_cursor.isNull(_cursorIndexOfUuid)) {
              _tmp_1 = null;
            } else {
              _tmp_1 = _cursor.getString(_cursorIndexOfUuid);
            }
            _result.uuid = __tripTypeConverter.toUUID(_tmp_1);
            if (_cursor.isNull(_cursorIndexOfTitle)) {
              _result.title = null;
            } else {
              _result.title = _cursor.getString(_cursorIndexOfTitle);
            }
            if (_cursor.isNull(_cursorIndexOfDestination)) {
              _result.destination = null;
            } else {
              _result.destination = _cursor.getString(_cursorIndexOfDestination);
            }
            if (_cursor.isNull(_cursorIndexOfDate)) {
              _result.date = null;
            } else {
              _result.date = _cursor.getString(_cursorIndexOfDate);
            }
            if (_cursor.isNull(_cursorIndexOfDuration)) {
              _result.duration = null;
            } else {
              _result.duration = _cursor.getString(_cursorIndexOfDuration);
            }
          } else {
            _result = null;
          }
          return _result;
        } finally {
          _cursor.close();
        }
      }

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

  public static List<Class<?>> getRequiredConverters() {
    return Collections.emptyList();
  }
}

I’ve been told I need to use Executor for INSERT, UPDATE and DELETE so they don’t get block the main thread, so I’m not sure how to fix this without just removing the executors.

As far as I can figure, there’s no actual Runnable object to return, so it doesn’t know what to do? If I’ve got that wrong please correct me.

But yeah, I just can’t figure out how to get around the executor wanting a Runnable return type, but there being no Runnable to return. Any help would be appreciated

Advertisement

Answer

You are trying to tell room to return a Runnable from the insert. Room knows that an @Insert can only return void or Long/long (the rowid of the inserted row).

  • if the @Insert inserts multiple rows then it can return void, long[] or Long[].
  • if you were look at the Build log, then the

You can’t have :-

@Insert
Runnable insertTrip(Trip trip);

It must be one of the following:-

@Insert
void insertTrip(Trip trip);

or

@Insert
long insertTrip(Trip trip);

or

@Insert
Long insertTrip(Trip trip);

Similar for @Update and @Delete except they return int (the number or affected rows)

To get/use the Runnable you could use :-

void insertTrip(Trip trip){
    executor.execute(new Runnable() {
        @Override
        public void run() {
            tripDao.insertTrip(trip);
        }
    });
}
  • obviously likewise for the others.

Working example

Using (note with a simple Trip class but all other classes as per your question bar the changes above) :-

    TripRepository.initialise(this);
    Trip atrip = new Trip();
    atrip.tripName = "My Trip";
    TripRepository.get().insertTrip(atrip);

Results in :-

enter image description here

Advertisement