房间编译问题 - 列引用了一个外键,但它不是索引的一部分。

7

我是Android应用程序开发的新手,正在创建一个包含Trips和存储位置的应用程序。

我遇到了编译错误:“trip_Id列引用了外键,但它不是索引的一部分。每当父表被修改时,这可能触发完整的表扫描,因此您强烈建议创建涵盖此列的索引。”

我有2个表:Trip和Location。

我尝试在它们各自的类中索引tripId和locationId,但这并没有解决问题。

一个Trip有其id(PK)、标题、描述和优先级。

一个Location有其locationId(PK)、tripId(FK)、位置名称和地点的经纬度。

@Entity(tableName = "location_table",
        foreignKeys = @ForeignKey(entity = Trip.class, parentColumns = "location_Id", childColumns = "trip_Id"),
        indices = {@Index(value = {"locationId"}, unique = true)})
public class Location {

    @PrimaryKey(autoGenerate = true)
    private int locationId;

    @ColumnInfo (name = "trip_Id")
    private int tripId;

    private String locationName;

    @TypeConverters(LatLngConverter.class)
    private LatLng latLng;


@Entity(tableName = "trip_table", indices = {@Index(value = {"id"}, unique = true)})

public class Trip {

    @PrimaryKey(autoGenerate = true) // with each new row SQLite will automatically increment this ID so it will be unique
    @ColumnInfo (name = "location_Id")
    private int id;

    private String title;

    private String description;

    private int priority;

我似乎找不出问题在哪里

2个回答

7
那个消息是一个警告,可能会出现其他错误(请参见第二个建议的行)。例如。

enter image description here

使用indices = {@Index(value = {"locationId"}, unique = true),@Index(value = {"trip_Id"})})可以解决这个警告。 然而,在locationId已经作为主键被索引的情况下,没有必要再创建一个(额外的)索引(这将是浪费且低效的)。因此建议您使用:
indices = {@Index(value = {"trip_Id"})})

我认为您的整体问题在于您正在引用对象的变量名称作为列名,当您有 @ColumnInfo(name ="????") 时,应该引用给定的名称。
  • 即,???? 是底层表中的列名。

在 Trip 中,您还应该使用 location_Id 而不是 id

@Entity(tableName = "trip_table", indices = {@Index(value = {"location_Id"}, unique = true)})

这解决了问题,但现在我又遇到了另一个错误。“错误:com.example.travelplanner.Location的外键引用了trip_table表,但该表在数据库中不存在。也许您忘记在@Database注释的实体列表中添加所引用的实体了?”我不明白这是什么意思。我先创建了Trip数据库,然后再添加Location数据库,一切都很好,可以将数据放置并在RecyclerView上显示。 - Ferain
1
@Ferain 在 @Database 注解中,你需要在实体列表中指定 **Trip.class**。 - MikeT

2
我在拥有很多外键时遇到了这个问题。经过很多试错,我发现我设置索引的方式是错误的...哎呀。:P 错误的:
indices = [
    Index("active_color_style_id",
        "ambient_color_style_id",
        "hour_hand_dimensions_id",
        "minute_hand_dimensions_id",
        "second_hand_dimensions_id")
]

正确:

indices = [
    Index("active_color_style_id"),
    Index("ambient_color_style_id"),
    Index("hour_hand_dimensions_id"),
    Index("minute_hand_dimensions_id"),
    Index("second_hand_dimensions_id")
]

完整示例:

@Entity(
    tableName = "analog_watch_face_table",
    foreignKeys = [
        ForeignKey(
            entity = WatchFaceColorStyleEntity::class,
            parentColumns = ["id"],
            childColumns = ["active_color_style_id"],
            onDelete = NO_ACTION
        ),
        ForeignKey(
            entity = WatchFaceColorStyleEntity::class,
            parentColumns = ["id"],
            childColumns = ["ambient_color_style_id"],
            onDelete = NO_ACTION
        ),
        ForeignKey(
            entity = WatchFaceArmDimensionsEntity::class,
            parentColumns = ["id"],
            childColumns = ["hour_hand_dimensions_id"],
            onDelete = NO_ACTION
        ),
        ForeignKey(
            entity = WatchFaceArmDimensionsEntity::class,
            parentColumns = ["id"],
            childColumns = ["minute_hand_dimensions_id"],
            onDelete = NO_ACTION
        ),
        ForeignKey(
            entity = WatchFaceArmDimensionsEntity::class,
            parentColumns = ["id"],
            childColumns = ["second_hand_dimensions_id"],
            onDelete = NO_ACTION
        )
    ],
    indices = [
        Index("active_color_style_id"),
        Index("ambient_color_style_id"),
        Index("hour_hand_dimensions_id"),
        Index("minute_hand_dimensions_id"),
        Index("second_hand_dimensions_id")
    ]
)

我该如何进行迁移呢?我的意思是,我已经设置了没有索引的Room(用户已将其设置为这样),那么我该如何让他们迁移到新的更改呢? - android developer
你可以升级版本并将它们从旧版本迁移到新版本。这里是指南 - codingjeremy
我知道迁移是如何工作的。我只是在这种情况下询问,创建索引是否可行。我能否修改一个表以拥有索引?还是我必须为每个没有索引的表创建一个全新的表,填充它,并删除先前的表? - android developer
哦,我明白了,抱歉。嗯...那是个好问题。当我开始使用第一个版本时,我的表格上没有索引,所以我认为添加它们应该没问题,但是这只是一个简化的样例(不是生产应用),我很快就通过了原型制作。你可能需要测试一下。抱歉我没有更好的答案。 :-/ - codingjeremy
我的意思是:在迁移中如何向之前没有索引的表添加索引? - android developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接