summaryrefslogtreecommitdiff
path: root/android/arch/persistence/room/Relation.java
blob: 72066992b88e2676cdd74753afd8aae7fa012dc6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.arch.persistence.room;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 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.
 *
 * <pre>
 * {@literal @}Entity
 * public class Pet {
 *     int userId;
 *     String name;
 *     // other fields
 * }
 * public class UserNameAndAllPets {
 *   public int id;
 *   public String name;
 *   {@literal @}Relation(parentColumn = "id", entityColumn = "userId")
 *   public List&lt;Pet&gt; pets;
 * }
 *
 * {@literal @}Dao
 * public interface UserPetDao {
 *     {@literal @}Query("SELECT id, name from User WHERE age &gt; :minAge")
 *     public List&lt;UserNameAndAllPets&gt; loadUserAndPets(int minAge);
 * }
 * </pre>
 * <p>
 * The type of the field annotated with {@code Relation} must be a {@link java.util.List} or
 * {@link java.util.Set}. By default, the {@link Entity} type is inferred from the return type.
 * If you would like to return a different object, you can specify the {@link #entity()} property
 * in the annotation.
 * <pre>
 * public class User {
 *     int id;
 *     // other fields
 * }
 * public class PetNameAndId {
 *     int id;
 *     String name;
 * }
 * public class UserAllPets {
 *   {@literal @}Embedded
 *   public User user;
 *   {@literal @}Relation(parentColumn = "id", entityColumn = "userId", entity = Pet.class)
 *   public List<PetNameAndId> pets;
 * }
 * {@literal @}Dao
 * public interface UserPetDao {
 *     {@literal @}Query("SELECT * from User WHERE age &gt; :minAge")
 *     public List&lt;UserAllPets&gt; loadUserAndPets(int minAge);
 * }
 * </pre>
 * <p>
 * In the example above, {@code PetNameAndId} is a regular but all of fields are fetched
 * from the {@code entity} defined in the {@code @Relation} annotation (<i>Pet</i>).
 * {@code PetNameAndId} could also define its own relations all of which would also be fetched
 * automatically.
 * <p>
 * If you would like to specify which columns are fetched from the child {@link Entity}, you can
 * use {@link #projection()} property in the {@code Relation} annotation.
 * <pre>
 * public class UserAndAllPets {
 *   {@literal @}Embedded
 *   public User user;
 *   {@literal @}Relation(parentColumn = "id", entityColumn = "userId", entity = Pet.class,
 *           projection = {"name"})
 *   public List<String> petNames;
 * }
 * </pre>
 * <p>
 * Note that {@code @Relation} annotation can be used only in Pojo classes, an {@link Entity} class
 * cannot have relations. This is a design decision to avoid common pitfalls in {@link 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 {@link Entity}.
 *
 * Note that the {@code @Relation} annotated field cannot be a constructor parameter, it must be
 * public or have a public setter.
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface Relation {
    /**
     * The entity to fetch the item from. You don't need to set this if the entity matches the
     * type argument in the return type.
     *
     * @return The entity to fetch from. By default, inherited from the return type.
     */
    Class entity() default Object.class;

    /**
     * Reference field in the parent Pojo.
     * <p>
     * If you would like to access to a sub item of a {@link Embedded}d field, you can use
     * the {@code .} notation.
     * <p>
     * For instance, if you have a {@link Embedded}d field named {@code user} with a sub field
     * {@code id}, you can reference it via {@code user.id}.
     * <p>
     * This value will be matched against the value defined in {@link #entityColumn()}.
     *
     * @return The field reference in the parent object.
     */
    String parentColumn();

    /**
     * The field path to match in the {@link #entity()}. This value will be matched against the
     * value defined in {@link #parentColumn()}.
     */
    String entityColumn();

    /**
     * If sub fields should be fetched from the entity, you can specify them using this field.
     * <p>
     * By default, inferred from the the return type.
     *
     * @return The list of columns to be selected from the {@link #entity()}.
     */
    String[] projection() default {};
}