[英]How do I add a foreign key to my entity in Room 2.3.0?
I have a project that I have worked with Room 2.2.5, I just updated to version 2.3.0 this is the code of an entity called photo:我有一个使用 Room 2.2.5 的项目,我刚刚更新到 2.3.0 版本,这是一个名为 photo 的实体的代码:
@Entity(tableName = Photo.TABLE_NAME, foreignKeys = @ForeignKey(entity = Event.class,
parentColumns = "_id",
childColumns = "id_event_ft",
onDelete = ForeignKey.CASCADE))
public class Photo {
public static final String TABLE_NAME = "Photo";
public static final String COLUMN_ID = BaseColumns._ID;
@PrimaryKey(autoGenerate = true)
@ColumnInfo(index = true, name = COLUMN_ID)
public Long id_photo;
@ColumnInfo(name = "path")
private String path;
@ForeignKey(entity = Event.class,
parentColumns = "_id",
childColumns = "id_event_ft",
onDelete = ForeignKey.CASCADE)
private Long id_event_ft;
public Photo(Long id_photo, String path, Long id_event_ft) {
this.id_photo = id_photo;
this.path = path;
this.id_event_ft = id_event_ft;
}
public Long getId_photo() {
return id_photo;
}
public void setId_photo(Long id_photo) {
this.id_photo = id_photo;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Long getId_event_ft() {
return id_event_ft;
}
public void setId_event_ft(Long id_event_ft) {
this.id_event_ft = id_event_ft;
}
}
Now I am getting the following error when trying to compile现在我在尝试编译时收到以下错误
error: annotation type not applicable to this kind of declaration @ForeignKey(entity = Event.class, parentColumns = "_id", childColumns = "id_event_ft", onDelete = ForeignKey.CASCADE) ^
错误:注释类型不适用于这种声明 @ForeignKey(entity = Event.class, parentColumns = "_id", childColumns = "id_event_ft", onDelete = ForeignKey.CASCADE) ^
The error is in the @ForeignKey that is above the variable private Long id_event_ft;
错误出现在变量
private Long id_event_ft;
In the documentation I found this:在文档中我发现了这个:
Added missing target to @ForeignKey annotation preventing its usage outside of the @Entity annotation.
向 @ForeignKey 注释添加了缺少的目标,以防止其在 @Entity 注释之外使用。 (Iced1e)
(Iced1e)
It is clear that using @ForeignKey outside of the @Entity annotation is no longer allowed, but then how do I bind the id_event_ft
variable to the foreign key?, How do I assign a value to it now?很明显,不再允许在 @Entity 注释之外使用 @ForeignKey ,但是我如何将
id_event_ft
变量绑定到外键?,我现在如何为其赋值?
I hope someone can help me, thank you very much我希望有人可以帮助我,非常感谢
if the relation is many photo for one event, use ORM Hibernate, this is the easiest way to define foreign key with constraint on your Photo Entity如果关系是一个事件的多张照片,请使用 ORM Hibernate,这是定义外键并限制照片实体的最简单方法
@ManyToOne
@JoinColumn(name = "id", nullable = false)
private Event id_event_ft;
Using ForeignKey does not automatically (magically) make a relationship.使用ForeignKey不会自动(神奇地)建立关系。 Rather it allows a relationship to be supported primarily by enforcing referential integrity.
相反,它允许主要通过强制引用完整性来支持关系。
That is it is defining a rule that says that the value of the child column ( id_event_ft ) MUST be a value that is present in the parent column ( _id ).也就是说,它定义了一条规则,即子列 ( id_event_ft ) 的值必须是父列 ( _id ) 中存在的值。 It also supports handling if there is a Foreign Key Conflict (eg
onDelete
as you have used).如果存在外键冲突,它还支持处理(例如您使用的
onDelete
)。
Actually providing a suitable value is something that you have to do programmatically, that is id adding a photo you have to determine which Event the photo is to be linked/related to.实际上,提供合适的值是您必须以编程方式执行的操作,即 id 添加照片,您必须确定照片要链接/相关的事件。
You can use @Relation to simplify extracting related data.您可以使用@Relation 来简化提取相关数据的过程。
So consider the following:所以考虑以下几点:
An Event Entity (nice and simple for demonstration)一个事件实体(很好而且简单的演示)
@Entity
public class Event {
@PrimaryKey(autoGenerate = true)
Long _id = null;
String other_columns;
public Event(){}
@Ignore
public Event(String other_columns) {
this.other_columns = other_columns;
}
}
A slightly changed Photo Entity:-稍微改变的照片实体:-
@Entity(tableName = Photo.TABLE_NAME,
foreignKeys = @ForeignKey(
entity = Event.class,
parentColumns = "_id",
childColumns = "id_event_ft",
onDelete = ForeignKey.CASCADE),
indices = @Index("id_event_ft") //<<<<<<<<<< ADDED as Room warns if omitted
)
public class Photo {
public static final String TABLE_NAME = "Photo";
public static final String COLUMN_ID = BaseColumns._ID;
@PrimaryKey(autoGenerate = true)
@ColumnInfo(index = true, name = COLUMN_ID)
public Long id_photo;
@ColumnInfo(name = "path")
private String path;
/* <<<<<<<< COMMENTED OUT >>>>>>>>>>
@ForeignKey(entity = Event.class,
parentColumns = "_id",
childColumns = "id_event_ft",
onDelete = ForeignKey.CASCADE)
*/
private Long id_event_ft;
public Photo(Long id_photo, String path, Long id_event_ft) {
this.id_photo = id_photo;
this.path = path;
this.id_event_ft = id_event_ft;
}
public Long getId_photo() {
return id_photo;
}
public void setId_photo(Long id_photo) {
this.id_photo = id_photo;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Long getId_event_ft() {
return id_event_ft;
}
public void setId_event_ft(Long id_event_ft) {
this.id_event_ft = id_event_ft;
}
}
For demonstration of retrieving via a relationship the POJO EventWithPhotos :-为了演示通过关系检索 POJO EventWithPhotos :-
public class EventWithPhotos {
@Embedded
Event event;
@Relation(entity = Photo.class,parentColumn = "_id",entityColumn = "id_event_ft")
List<Photo> photos;
}
Now a Dao AllDao :-现在是道AllDao :-
@Dao
interface AllDao {
@Insert
long insert(Event event);
@Insert
long insert(Photo photo);
@Transaction
@Query("SELECT * FROM event")
List<EventWithPhotos> getAllEventsWithPhotos();
}
How do I assign a value to it now?
我现在如何为其赋值?
Now an example that puts it all together adding 2 Events the first with 2 photos, the second with 1 photo.现在是一个将所有事件放在一起的示例,第一个事件有 2 张照片,第二个事件有 1 张照片。 Note the different techniques used:-
请注意使用的不同技术:-
dao = db.getAllDao();
// Prepare to add an Event
Event newEvent = new Event();
newEvent.other_columns = "Event1";
// Add the Event retrieving the id (_id column)
long eventId = dao.insert(newEvent);
// Prepare a photo to be added to Event1
Photo newPhoto = new Photo(null,"photo1",eventId);
// Add the Photo to Event1
long photoid = dao.insert(newPhoto);
// Add second photo to Event 1 using the 2nd constructor
dao.insert(new Photo(null,"photo2",eventId));
// Add Event2 with a photo all in a single line (again using the 2nd constrcutor)
long event2Id;
dao.insert(new Photo(null,"photo3",event2Id = dao.insert(new Event("Event2"))));
// Get and output Each Event with the Photos for that Event
List<EventWithPhotos> allEventsWithPhotosList = dao.getAllEventsWithPhotos();
for (EventWithPhotos ewp: allEventsWithPhotosList) {
Log.d("EVENTPHOTOINFO","Event is " + ewp.event.other_columns);
for (Photo p: ewp.photos) {
Log.d("EVENTWITHPHOTO","\tPhoto is " + p.getPath() + " ID is " + p.getId_photo());
}
}
Result结果
When run the log contains:-运行时日志包含:-
D/EVENTPHOTOINFO: Event is Event1
D/EVENTWITHPHOTO: Photo is photo1 ID is 1
D/EVENTWITHPHOTO: Photo is photo2 ID is 2
D/EVENTPHOTOINFO: Event is Event2
D/EVENTWITHPHOTO: Photo is photo3 ID is 3
The Database (view with Database Inspector) shows:-数据库(使用数据库检查器查看)显示:-
The Event table:-事件表:-
The Photo table:-照片表:-
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.