Relation
@Target([AnnotationTarget.FIELD, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER]) class Relation
androidx.room.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 public class Song { @ PrimaryKey int songId; int albumId; String name; // other fields } public class AlbumNameAndAllSongs { int id; String name; @Relation(parentColumn = "id", entityColumn = "albumId") List<Song> songs; } @Dao public interface MusicDao { @Query("SELECT id, name FROM Album") List<AlbumNameAndAllSongs> loadAlbumAndSongs(); }
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.
public class Album { int id; // other fields } public class SongNameAndId { int songId; String name; } public class AlbumAllSongs { @Embedded Album album; @Relation(parentColumn = "id", entityColumn = "albumId", entity = Song.class) List<SongNameAndId> songs; } @Dao public interface MusicDao { @Query("SELECT * from Album") List<AlbumAllSongs> loadAlbumAndSongs(); }
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.
public class AlbumAndAllSongs { @Embedded Album album; @Relation( parentColumn = "id", entityColumn = "albumId", entity = Song.class, projection = {"name"}) List<String> songNames; }
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 | |
---|---|
<init>(entity: KClass<*>, parentColumn: String, entityColumn: String, associateBy: Junction, projection: Array<String>) A convenience annotation which can be used in a POJO to automatically fetch relation entities. |
Properties | |
---|---|
Junction |
The entity or view to be used as a associative table (also known as a junction table) when fetching the relating entities. |
KClass<*> |
The entity or view to fetch the item from. |
String |
The column to match in the |
String |
Reference column in the parent POJO. |
Array<String> |
If sub columns should be fetched from the entity, you can specify them using this field. |
Public constructors
<init>
Relation(
entity: KClass<*>,
parentColumn: String,
entityColumn: String,
associateBy: Junction,
projection: Array<String>)
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 public class Song { @ PrimaryKey int songId; int albumId; String name; // other fields } public class AlbumNameAndAllSongs { int id; String name; @Relation(parentColumn = "id", entityColumn = "albumId") List<Song> songs; } @Dao public interface MusicDao { @Query("SELECT id, name FROM Album") List<AlbumNameAndAllSongs> loadAlbumAndSongs(); }
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.
public class Album { int id; // other fields } public class SongNameAndId { int songId; String name; } public class AlbumAllSongs { @Embedded Album album; @Relation(parentColumn = "id", entityColumn = "albumId", entity = Song.class) List<SongNameAndId> songs; } @Dao public interface MusicDao { @Query("SELECT * from Album") List<AlbumAllSongs> loadAlbumAndSongs(); }
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.
public class AlbumAndAllSongs { @Embedded Album album; @Relation( parentColumn = "id", entityColumn = "albumId", entity = Song.class, projection = {"name"}) List<String> songNames; }
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
.
See Also
Properties
associateBy
val associateBy: Junction
The entity or view to be used as a associative table (also known as a junction table) when fetching the relating entities.
Return | |
---|---|
Junction |
The junction describing the associative table. By default, no junction is specified and none will be used. |
See Also
entity
val entity: KClass<*>
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.
Return | |
---|---|
KClass<*> |
The entity or view to fetch from. By default, inherited from the return type. |
entityColumn
val entityColumn: String
The column to match in the entity()
.
In a one-to-one or one-to-many relation, this value will be matched against the column defined in parentColumn()
()}. In a many-to-many using associateBy()
then this value will be matched against the Junction#entityColumn()
parentColumn
val parentColumn: String
Reference column in the parent POJO.
In a one-to-one or one-to-many relation, this value will be matched against the column defined in entityColumn()
. In a many-to-many using associateBy()
then this value will be matched against the Junction#parentColumn()
Return | |
---|---|
String |
The column reference in the parent object. |