# RawQuery

Artifact: [androidx.room:room-common](https://developer.android.com/jetpack/androidx/releases/room) [View Source](https://cs.android.com/search?q=file:androidx/room/RawQuery.kt+class:androidx.room.RawQuery) Added in [2.0.0](https://developer.android.com/jetpack/androidx/releases/room#2.0.0)

*** ** * ** ***


```
@Target(allowedTargets = [AnnotationTarget.FUNCTION])
@Retention(value = AnnotationRetention.BINARY)
public annotation RawQuery
```

<br />

*** ** * ** ***

Marks a method in a `https://developer.android.com/reference/androidx/room/Dao` annotated class as a raw query method where you can pass the query as a `https://developer.android.com/reference/androidx/room/RoomRawQuery` or androidx.sqlite.db.SupportSQLiteQuery.

```
@Dao
interface RawDao {
    @RawQuery
    fun getSongViaQuery(query: RoomRawQuery): Song
}

// Usage of RawDao
val query = RoomRawQuery(
    sql = "SELECT * FROM Song WHERE id = ? LIMIT 1",
    onBindStatement = { it.bindLong(1, songId) }
)
val song = rawDao.getSongViaQuery(query)
```

Room will generate the code based on the return type of the function and failure to pass a proper query will result in a runtime failure or an undefined result.

If you know the query at compile time, you should always prefer `https://developer.android.com/reference/androidx/room/Query` since it validates the query at compile time and also generates more efficient code, since Room can compute the query result at compile time (e.g. it does not need to account for possibly missing columns in the result).

On the other hand, `@RawQuery` serves as an escape hatch where you can build your own SQL query at runtime but still use Room to convert it into objects.

`@RawQuery` methods must return a non-void type. If you want to execute a raw query that does not return any value, use androidx.room.RoomDatabase.query methods.

`@RawQuery` methods can only be used for read queries. For write queries, use androidx.room.RoomDatabase.openHelper.

**Observable Queries:**

`@RawQuery` methods can return observable types but you need to specify which tables are accessed in the query using the `https://developer.android.com/reference/androidx/room/RawQuery#observedEntities()` field in the annotation.

```
@Dao
interface RawDao {
    @RawQuery(observedEntities = Song::class)
    fun getSongs(query: RoomRawQuery): Flow<List<Song>>
}

// Usage of RawDao
val liveSongs = rawDao.getSongs(
    RoomRawQuery("SELECT * FROM song ORDER BY name DESC")
)
```

**Returning POJOs:**

`@RawQuery` can also return plain old java objects, similar to `https://developer.android.com/reference/androidx/room/Query` methods.

```
data class NameAndReleaseYear (
    val name: String,
    @ColumnInfo(name = "release_year")
    val year: Int
)

@Dao
interface RawDao {
    @RawQuery
    fun getNameAndReleaseYear(query: RoomRawQuery): NameAndReleaseYear
}

// Usage of RawDao
val result: NameAndReleaseYear = rawDao.getNameAndReleaseYear(
    RoomRawQuery(
        sql = "SELECT * FROM song WHERE id = ?",
        onBindStatement = { it.bindLong(1, songId) }
    )
)
```

**POJOs with Embedded Fields:**

`@RawQuery` methods can return POJOs that include `https://developer.android.com/reference/androidx/room/Embedded` fields as well.

```
data class SongAndArtist (
    @Embedded
    val song: Song,
    @Embedded
    val artist: Artist
)

@Dao
interface RawDao {
    @RawQuery
    fun getSongAndArtist(query: RoomRawQuery): SongAndArtist
}

// Usage of RawDao
val result: = rawDao.getSongAndArtist(
    RoomRawQuery("SELECT * FROM Song, Artist WHERE Song.artistId = Artist.id LIMIT 1")
)
```

**Relations:**

`@RawQuery` return types can also be objects with `https://developer.android.com/reference/androidx/room/Relation`.

```
data class AlbumAndSongs {
    @Embedded
    val album: Album,
    @Relation(parentColumn = "id", entityColumn = "albumId")
    val songs: List<Song>
}

@Dao
interface RawDao {
    @RawQuery
    fun getAlbumAndSongs(query: RoomRawQuery): List<AlbumAndSongs>
}

// Usage of RawDao
val result = rawDao.getAlbumAndSongs(
    RoomRawQuery("SELECT * FROM album")
)
```

## Summary

| ### Public methods |
|---|---|
| `final @https://developer.android.com/reference/androidx/annotation/NonNull KClass[]` | `https://developer.android.com/reference/androidx/room/RawQuery#getObservedEntities()()` Denotes the list of entities which are accessed in the provided query and should be observed for invalidation if the query is observable. |

## Public methods

### getObservedEntities

```
public final @NonNull KClass[] getObservedEntities()
```

Denotes the list of entities which are accessed in the provided query and should be observed for invalidation if the query is observable.

The listed classes should either be annotated with `https://developer.android.com/reference/androidx/room/Entity` or they should reference to at least 1 `https://developer.android.com/reference/androidx/room/Entity` (via `https://developer.android.com/reference/androidx/room/Embedded` or `https://developer.android.com/reference/androidx/room/Relation`).

Providing this field in a non-observable query has no impact.

```
@Dao
interface RawDao {
  @RawQuery(observedEntities = Song::class)
  fun getSongs(query: RoomRawQuery): Flow<List<Song>>
}
val liveSongs: = rawDao.getSongs(
    RoomRawQuery("SELECT * FROM song ORDER BY name DESC")
)
```

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull KClass[]` | List of entities that should invalidate the query if changed. |