Android
Room Database
Entity Update
SQLite
Mobile Development

Update some specific field of an entity in android Room

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Room, partial updates are usually better than replacing an entire entity when only one field changes. This is common for status flags, counters, and timestamps. The safest implementation is to create explicit DAO update methods per business action so data changes stay predictable and easy to test.

Why Partial Update Is Important

Using @Update on a full entity is convenient, but it updates all mapped columns. If your in-memory entity is stale or partially populated, you can overwrite values unintentionally.

For example, toggling a boolean flag should not risk changing unrelated columns such as email or display name.

Entity Baseline

kotlin
1import androidx.room.Entity
2import androidx.room.PrimaryKey
3
4@Entity(tableName = "users")
5data class UserEntity(
6    @PrimaryKey val id: Long,
7    val name: String,
8    val email: String,
9    val isActive: Boolean,
10    val loginCount: Int,
11    val updatedAtEpochMs: Long
12)

A clear schema helps you define focused updates.

DAO Methods For Specific Fields

Define one query per targeted update.

kotlin
1import androidx.room.Dao
2import androidx.room.Query
3
4@Dao
5interface UserDao {
6
7    @Query(
8        """
9        UPDATE users
10        SET isActive = :active,
11            updatedAtEpochMs = :updatedAt
12        WHERE id = :userId
13        """
14    )
15    suspend fun updateActiveState(userId: Long, active: Boolean, updatedAt: Long): Int
16
17    @Query(
18        """
19        UPDATE users
20        SET loginCount = loginCount + 1,
21            updatedAtEpochMs = :updatedAt
22        WHERE id = :userId
23        """
24    )
25    suspend fun incrementLoginCount(userId: Long, updatedAt: Long): Int
26}

Returning Int gives affected row count so callers can detect missing records.

Repository Layer With Business Semantics

Wrap DAO calls in intent-driven methods.

kotlin
1class UserRepository(private val userDao: UserDao) {
2
3    suspend fun deactivateUser(userId: Long) {
4        val rows = userDao.updateActiveState(
5            userId = userId,
6            active = false,
7            updatedAt = System.currentTimeMillis()
8        )
9        require(rows == 1) { "No user updated for id=$userId" }
10    }
11
12    suspend fun recordSuccessfulLogin(userId: Long) {
13        val rows = userDao.incrementLoginCount(
14            userId = userId,
15            updatedAt = System.currentTimeMillis()
16        )
17        require(rows == 1) { "No user updated for id=$userId" }
18    }
19}

This keeps update logic consistent and central.

Transactions For Multi-Step Updates

If one user action updates multiple tables, use a transaction.

kotlin
1import androidx.room.Dao
2import androidx.room.Query
3import androidx.room.Transaction
4
5@Dao
6interface SessionDao {
7    @Query("UPDATE users SET isActive = 0 WHERE id = :userId")
8    suspend fun deactivate(userId: Long)
9
10    @Query("INSERT INTO audit_logs(userId, message, createdAt) VALUES(:userId, :msg, :createdAt)")
11    suspend fun addAudit(userId: Long, msg: String, createdAt: Long)
12
13    @Transaction
14    suspend fun deactivateWithAudit(userId: Long) {
15        deactivate(userId)
16        addAudit(userId, "deactivated", System.currentTimeMillis())
17    }
18}

Atomic updates protect consistency under failures.

Reactive UI Considerations

Partial updates still trigger Room invalidation and refresh Flow or LiveData observers. You do not lose reactive behavior by updating one column.

kotlin
@Query("SELECT * FROM users WHERE id = :id")
fun observeUser(id: Long): kotlinx.coroutines.flow.Flow<UserEntity>

That means you can optimize writes without changing UI data flow architecture.

Performance Notes

Partial updates often reduce write volume and reduce conflict probability when concurrent operations touch different fields. They also shorten SQL statements and simplify change history interpretation.

For high-frequency counters, prefer incremental SQL updates in the database instead of read-modify-write on client side, which can lose updates under concurrency.

Common Pitfalls

  • Using @Update with stale entities and overwriting unrelated fields.
  • Ignoring affected row count and silently missing invalid IDs.
  • Forgetting to update metadata such as updatedAtEpochMs.
  • Performing read-modify-write counters outside SQL and losing increments.
  • Skipping transactions for multi-table operations that must be atomic.

Summary

  • Use explicit DAO @Query methods for field-level updates in Room.
  • Return and validate affected row count for safety.
  • Express updates as business actions in repository methods.
  • Use transactions when one action spans multiple writes.
  • Keep counter and state transitions in SQL for correctness under concurrency.

Course illustration
Course illustration

All Rights Reserved.