@RawQuery and Reactive Responses
Earlier, we saw that you can use @RawQuery
to execute queries where either:
- You do not know the SQL statement at compile time, as it needs to be assembled from pieces at runtime, or
- The table being queried is not associated with a Room
@Entity
If you attempt to return a reactive result from the @RawQuery
method (e.g., a Flowable
, a LiveData
), and the core object of the result is not an @Entity
, you will crash at build time, with:
Observable query return type (LiveData, Flowable, DataSource, DataSourceFactory etc) can only be used with SELECT queries that directly or indirectly (via @Relation, for example) access at least one table. For @RawQuery, you should specify the list of tables to be observed via the observedEntities field.
Room wants to be able to deliver updates to your reactive object when the underlying table’s content changes, and it can only do that if it knows the table.
For cases where there is a clear @Entity
(or perhaps more than one) whose changes should trigger an updated result to be delivered to you reactively, add the observedEntities
property to the @RawQuery
annotation, with the .class
reference(s) of the entities that should be observed. If anything associated with those entities changes, Room will re-deliver a fresh result to you.
For cases where the table being queried is not associated with a Room @Entity
, either:
- Do not return a reactive type, or
- Lie to Room and supply some arbitrary entity in
observedEntities
, just to make the error go away
Hopefully, this requirement will be relaxed, as not every situation calls for this sort of automatic-update delivery. For example, in the chapter on full-text searching in Room, we will see an example of using @RawQuery
with a reactive response type and having to provide a “fake” value for observedEntities
, just to eliminate the error.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.