Room Database Quiz

DATA › Storage

Which statement about returning a Flow from a Room @Query is correct?

Answer: Room emits a fresh value whenever the queried tables change

Observable Flow queries automatically emit a fresh result on every relevant table change, and they must not be marked suspend because the stream is already asynchronous.

You increase the @Database version from 1 to 2 but provide no Migration and no destructive fallback. What happens?

Answer: Room throws an IllegalStateException when the DB is opened

Without a migration path or a destructive fallback, Room cannot reconcile the old and new schemas and throws an IllegalStateException at runtime.

You want to persist a Date field in a Room entity. What is the correct approach?

Answer: Use @TypeConverter methods to convert Date to and from Long

SQLite only stores primitives, String, and byte[], so a Date needs a type converter that maps it to a storable type such as Long.

What is the correct way to fetch a User together with their list of Pets in a single Room result?

Answer: Create a POJO with @Embedded User and @Relation List<Pet>

Room maps relationships via a POJO that embeds the parent and uses @Relation to link the child list; Room runs a second query to fill it. Entities themselves cannot hold direct references to other entities.

A @Query references a column name that contains a typo. When is the error surfaced?

Answer: At compile time, in Room's annotation-processing step

Room validates @Query SQL against the schema at build time, so an unknown column or syntax error fails compilation rather than crashing later.

A method annotated @Insert(onConflict = OnConflictStrategy.REPLACE) inserts a row whose primary key already exists. What happens?

Answer: The existing row is deleted, then the new row is inserted

REPLACE removes the conflicting row and inserts the new one. IGNORE would keep the existing row, and ABORT (the default) would throw on conflict.

Which statement about Room migrations is true?

Answer: @AutoMigration needs an AutoMigrationSpec for ambiguous renames or drops

Auto-migrations rely on exported schemas to handle clear changes, but ambiguous operations such as renaming or deleting tables/columns require an AutoMigrationSpec to disambiguate.

What must the class annotated with @Database look like?

Answer: Abstract class extending RoomDatabase with abstract DAO accessors

The @Database class is an abstract class extending RoomDatabase with abstract accessor methods for each DAO; Room generates the concrete implementation at build time via KSP.

You call a non-suspend DAO query that returns List<User> directly from the main thread. What happens by default?

Answer: Room throws IllegalStateException unless allowMainThreadQueries()

Synchronous queries on the main thread throw IllegalStateException to prevent UI jank; you must use suspend/Flow queries or explicitly opt in with allowMainThreadQueries().

An entity has @PrimaryKey(autoGenerate = true) on a Long id. How do you let Room assign new ids on insert?

Answer: Leave the id at 0 and SQLite assigns the next rowId on insert

With autoGenerate = true on a Long key, leaving the id at 0 lets SQLite generate the next rowId; @Insert then returns that generated value as a Long.

An entity declares a @ForeignKey to a parent table with onDelete = ForeignKey.CASCADE. What does deleting a parent row do?

Answer: Deleting the parent row automatically deletes the child rows that reference it

onDelete = CASCADE propagates the parent deletion to all referencing child rows; foreign key constraints are real runtime constraints that you must opt into with @ForeignKey.

What is the correct way to model a many-to-many relationship (e.g. Students and Courses) in Room?

Answer: Define a junction entity, then use @Relation with associateBy = @Junction

Many-to-many requires an associative (junction) entity holding both keys, and Room links the two sides via @Relation with associateBy = @Junction pointing at that entity.

Why is it recommended to annotate a DAO method that returns an @Relation POJO with @Transaction?

Answer: Room's multiple relation SELECTs then run atomically and stay consistent

Fetching a parent plus its @Relation children involves several separate queries; wrapping them in @Transaction prevents another write from interleaving and producing an inconsistent combined result.

What can a method annotated @Update return?

Answer: An Int with the number of rows actually updated

@Update can optionally return an Int with the count of rows updated (matched by primary key); @Insert is the one that returns rowId Long values.

Back to Room Database