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

A convenience annotation which can be used in a POJO to automatically fetch relation entities. When the POJO is returned from a query, all of its relations are also fetched by Room.

@Entity
data class Song (
@PrimaryKey
val songId: Int,
val albumId: Int,
val name: String
// other fields
)

data class AlbumNameAndAllSongs (
val id: Int,
val name: String,
@Relation(parentColumn = "id", entityColumn = "albumId")
val songs: List<Song>
)

@Dao
public interface MusicDao {
@Query("SELECT id, name FROM Album")
fun loadAlbumAndSongs(): List<AlbumNameAndAllSongs>
}

For a one-to-many or many-to-many relationship, the type of the field annotated with Relation must be a java.util.List or java.util.Set.

By default, the Entity type is inferred from the return type. If you would like to return a different object, you can specify the entity property in the annotation.

data class Album (
val id: Int
// other fields
)

data class SongNameAndId (
val songId: Int,
val name: String
)

data class AlbumAllSongs (
@Embedded
val album: Album,
@Relation(parentColumn = "id", entityColumn = "albumId", entity = Song.class)
val songs: List<SongNameAndId>
)

@Dao
public interface MusicDao {
@Query("SELECT * from Album")
val loadAlbumAndSongs(): List<AlbumAllSongs>
}

In the example above, SongNameAndId is a regular POJO but all of fields are fetched from the entity defined in the @Relation annotation Song. SongNameAndId could also define its own relations all of which would also be fetched automatically.

If you would like to specify which columns are fetched from the child Entity, you can use projection property in the Relation annotation.

data class AlbumAndAllSongs (
@Embedded
val album: Album,
@Relation(
parentColumn = "id",
entityColumn = "albumId",
entity = Song.class,
projection = {"name"})
val songNames: List<String>
)

If the relationship is defined by an associative table (also know as junction table) then you can use associateBy to specify it. This is useful for fetching many-to-many relations.

Note that @Relation annotation can be used only in POJO classes, an Entity class cannot have relations. This is a design decision to avoid common pitfalls in Entity setups. You can read more about it in the main Room documentation. When loading data, you can simply work around this limitation by creating POJO classes that extend the Entity.

Summary

Public constructors

Public methods

getAssociateBy

public final @NonNull Junction getAssociateBy()

The entity or view to be used as a associative table (also known as a junction table) when fetching the relating entities.

Returns
@NonNull Junction

The junction describing the associative table. By default, no junction is specified and none will be used.

getEntity

public final @NonNull KClass<@NonNull ?> getEntity()

The entity or view to fetch the item from. You don't need to set this if the entity or view matches the type argument in the return type.

Returns
@NonNull KClass<@NonNull ?>

The entity or view to fetch from. By default, inherited from the return type.

getProjection

public final @NonNull String[] getProjection()

If sub columns should be fetched from the entity, you can specify them using this field.

By default, inferred from the the return type.

Returns
@NonNull String[]

The list of columns to be selected from the entity.

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.