Android Room创建多对多关系报错:主键引用的Room不存在于实体中
解决Room多对多关系中的“Room referenced in the primary key does not exists in the Entity”错误
看起来你在配置Room多对多关联时踩了个常见的坑——关联表(也就是你的MovieJoin类)的主键或外键引用出了问题。虽然你没贴出MovieJoin的代码,但根据错误提示,大概率是这个中间类的定义不符合Room的要求。我来帮你梳理正确的配置方式:
第一步:正确定义关联表(MovieJoin)
关联表需要同时存储电影和类型的ID作为复合主键,并且配置外键关联到对应的实体。以下是符合要求的示例代码:
@Entity( tableName = "movie_genre_join", // 复合主键:同时用movieId和genreId作为主键 primaryKeys = {"movieId", "genreId"}, foreignKeys = { // 关联MovieEntity @ForeignKey( entity = MovieEntity.class, parentColumns = {"id"}, // 对应MovieEntity的主键字段名 childColumns = {"movieId"}, // 关联表中存储电影ID的字段名 onDelete = ForeignKey.CASCADE // 可选:删除电影时自动删除关联记录 ), // 关联GenreEntity @ForeignKey( entity = GenreEntity.class, parentColumns = {"id"}, // 对应GenreEntity的主键字段名 childColumns = {"genreId"}, // 关联表中存储类型ID的字段名 onDelete = ForeignKey.CASCADE ) } ) public class MovieJoin { private int movieId; // 对应MovieEntity的id private int genreId; // 对应GenreEntity的id public MovieJoin(int movieId, int genreId) { this.movieId = movieId; this.genreId = genreId; } // Getters and Setters public int getMovieId() { return movieId; } public void setMovieId(int movieId) { this.movieId = movieId; } public int getGenreId() { return genreId; } public void setGenreId(int genreId) { this.genreId = genreId; } }
常见错误排查点
你遇到的错误通常由以下原因导致:
- 关联表字段名不匹配:比如你在
primaryKeys里写了一个关联表中不存在的字段,或者foreignKeys的parentColumns写错了实体的主键名(你的两个实体主键都是id,别写成其他名字)。 - 外键配置错误:
childColumns必须是关联表中实际存在的字段,parentColumns必须是对应实体的主键字段。 - 数据库类未包含关联表:确保你的Room Database类的
entities数组里同时包含MovieEntity、GenreEntity和MovieJoin。
验证多对多查询(可选)
配置好关联表后,你可以通过@Transaction和@Query来查询关联数据,比如获取某部电影的所有类型:
// 定义关联数据的封装类 public class MovieWithGenres { @Embedded private MovieEntity movie; @Relation( parentColumn = "id", entityColumn = "id", associateBy = @Junction( value = MovieJoin.class, parentColumn = "movieId", entityColumn = "genreId" ) ) private List<GenreEntity> genres; // Getters and Setters public MovieEntity getMovie() { return movie; } public void setMovie(MovieEntity movie) { this.movie = movie; } public List<GenreEntity> getGenres() { return genres; } public void setGenres(List<GenreEntity> genres) { this.genres = genres; } } // Dao层查询方法 @Dao public interface MovieDao { @Transaction @Query("SELECT * FROM movie WHERE id = :movieId") MovieWithGenres getMovieWithGenres(int movieId); }
按照这个方式调整你的MovieJoin类,应该就能解决这个错误了。
内容的提问来源于stack exchange,提问作者Andras Sanislo
相关产品推荐
相关产品推荐

