Java 如何向房间2.3.0中的实体添加外键?

Java 如何向房间2.3.0中的实体添加外键?,java,android,sqlite,android-room,Java,Android,Sqlite,Android Room,我有一个项目,我与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

我有一个项目,我与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;
    }
}
现在我在尝试编译时遇到以下错误

错误:注释类型不适用于此类声明 @ForeignKey(entity=Event.class,parentColumns=“\u id”,childColumns=“id\u Event\u ft”,onDelete=ForeignKey.CASCADE) ^

错误出现在变量
private Long id\u event\u ft上方的@ForeignKey中

在这本书中,我发现:

将缺少的目标添加到@ForeignKey注释中,以防止其在@Entity注释之外使用。(Iced1e)

显然,不再允许在@Entity注释之外使用@ForeignKey,但是如何将
id\u event\u ft
变量绑定到外键?现在如何为其赋值

我希望有人能帮助我,非常感谢你 @多对一 如果一个事件的关系是多张照片,请使用ORM Hibernate,这是定义带有照片实体约束的外键的最简单方法

@ManyToOne
@JoinColumn(name = "id", nullable = false)
private Event id_event_ft;

使用外键不会自动(神奇地)建立关系。相反,它允许主要通过强制引用完整性来支持关系

  • 外键(关系)不需要外键定义
也就是说,它定义了一条规则,规定子列(id\u event\u ft)的值必须是父列(\u id)中存在的值。它还支持处理外键冲突(例如,您使用的
onDelete

实际上,提供一个合适的值是您必须以编程方式完成的事情,即添加一张照片,您必须确定照片将链接/关联到哪个事件

您可以使用@Relation简化提取相关数据的过程

请考虑以下内容:

事件实体(用于演示的简洁明了)

  • 照片的父列将是\u id
  • 第二个被忽略(即被房间忽略)构造函数,否则房间会发出类似*警告的警告:有多个好的构造函数,房间会选择无参数构造函数*
稍有变化的照片实体:-

@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;
    }
}
数据库(使用数据库检查器查看)显示:-

事件表:-

照片表格:-

@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;
    }
}
public class EventWithPhotos {

    @Embedded
    Event event;
    @Relation(entity = Photo.class,parentColumn = "_id",entityColumn = "id_event_ft")
    List<Photo> photos;
}
@Dao
interface AllDao {

    @Insert
    long insert(Event event);
    @Insert
    long insert(Photo photo);
    @Transaction
    @Query("SELECT * FROM event")
    List<EventWithPhotos> getAllEventsWithPhotos();
}
    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());
        }
    }
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