Home > Blockchain >  Return the new rowId when a new row is added to the Room database
Return the new rowId when a new row is added to the Room database

Time:12-05

When I read the documentation from Android Developers, it states:

If the @Insert method receives a single parameter, it can return a long value, which is the new rowId for the inserted item.

This is exactly what I need! When a new row is inserted, I want to return the new rowId and use it in the activity. However I can't get this to work in my current setup (especially in combinations with suspend functions).

Room Entity

@Entity(
    tableName = "note_table",
    indices = [Index(
        value = ["db_key"],
        unique = true
    )]
)
data class NoteEntity(
    ...
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "db_key")
    val uid: Long? = null
)

Dao

@Dao
interface NoteEntityDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertNote(note: Note)
    ...
}

Repository

interface NoteRepository {

    suspend fun insertNote(note: Note)
    ...
}

Repository Implementation

class NoteRepositoryImplementation @Inject constructor(
    private val dao: NoteEntityDao
) : NoteRepository {

    override suspend fun insertNote(note: NoteEntity) {
        dao.insertNoteEntry(note)
    }

Use Case

class AddNoteUseCase(
    private val repository: NoteRepository
) {

    suspend fun execute(note: Note) {
        repository.insertNote(note)
    }
}

ViewModel

@HiltViewModel
class NoteViewModel @Inject constructor(
    private val noteUseCases: NoteUseCases
) : ViewModel() {

    fun insertNote(note: NoteEntity) {
        viewModelScope.launch {
            noteUseCases.addNoteUseCase.execute(note)
        }
    }

Activity

class NoteActivity : AppCompatActivity() {
...
val newNoteEntry = NoteEntity(
                    title = title,
                    description = description,
                    createdOn = createdOn,
                    createdBy = createdBy
                )

viewModel.insertNote(newNoteEntry)
...
}

CodePudding user response:

In your DAO, you just need to add a Long return type to the function signature:

suspend fun insertNote(note: Note): Long

And you can add it in your repository function and so on.

CodePudding user response:

Try below code.

Dao

@Dao
interface NoteEntityDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertNote(note: Note) : Long
}

Repository Implementation

class NoteRepositoryImplementation @Inject constructor( private val dao: NoteEntityDao ) : NoteRepository {

override suspend fun insertNote(note: NoteEntity):Long {
    return dao.insertNoteEntry(note)
}

ViewModel

@HiltViewModel
class NoteViewModel @Inject constructor(
    private val noteUseCases: NoteUseCases
) : ViewModel() {
    private val noteChannelFlow = Channel<NoteEvent>()
    val noteEvent = noteChannelFlow.receiveAsFlow()
    
    fun insertNote(note: NoteEntity) = viewModelScope.launch {
        noteChannelFlow.send(NoteEvent.Inserted(noteUseCases.addNoteUseCase.execute(note)))
    }
    sealed class NoteEvent {
        data class Inserted(val data: Long) : NoteEvent()
    }
}

Activity

class NoteActivity : AppCompatActivity() {
   ...
   lifecycle.coroutineScope.launchWhenStarted {
       viewModel.noteEvent.collect { event ->

        when(event){
          Log.d("DATA",event.data)
        }
     }
  }
}
  • Related