Kotlin Room使用POJO关联实体时触发‘实体类需标注@Entity’错误
问题根源及解决方案
错误原因
你遇到的Entity class must be annotated with @Entity错误,核心问题是你把用于关联查询的POJO类Rent标记成了@Entity实体。Room的规则是:
@Entity注解只能用于对应数据库表的实体类,这类类里不能包含@Relation注解的集合属性。@Relation是专门用于在非实体的POJO中关联多个实体类,实现一对多/多对一查询的。
你的Rent类本质是用来封装House和其关联的ApartmentOptions的组合数据,不是独立的数据库表,所以不能加@Entity注解。
修正步骤及代码
- 修改Rent类:移除@Entity注解,它只是一个普通的POJO类,用于承载关联查询结果
- 调整数据库类:从entities列表中移除Rent::class,因为它不是数据库实体
- 修改Dao层:
- 不能直接插入Rent,需要分别插入House和ApartmentOptions
- 调整查询方法,通过@Transaction关联House和ApartmentOptions,返回Rent对象
- 补充外键字段:ApartmentOptions需要添加关联House的
houseId字段,才能建立一对多关联关系
修正后的完整代码
// 普通POJO,用于封装关联查询结果,无需@Entity data class Rent( @Embedded val house: House, @Relation(parentColumn = "houseId", entityColumn = "houseId") val apartmentOptions: List<ApartmentOptions> ) @Entity data class House( @PrimaryKey(autoGenerate = true) val houseId: Int = 0, val houseName: String // 字段名避免和类名重复,避免解析混淆 ) @Entity data class ApartmentOptions( @PrimaryKey(autoGenerate = true) val apartmentId: Int = 0, val apartmentName: String, val isFree: Boolean, val houseId: Int // 添加外键,关联House的houseId ) @Dao interface RentDao { // 分别插入House和ApartmentOptions @Insert suspend fun insertHouse(house: House): Long // 返回插入后的houseId,用于关联ApartmentOptions @Insert suspend fun insertApartmentOptions(options: List<ApartmentOptions>) // 关联查询,通过@Transaction保证原子性 @Transaction @Query("SELECT * FROM House") fun getAllRents(): Flow<List<Rent>> // 查询单个Rent的示例 @Transaction @Query("SELECT * FROM House WHERE houseId = :houseId") fun getRentByHouseId(houseId: Int): Flow<Rent?> } @Database( entities = [House::class, ApartmentOptions::class], // 移除Rent::class version = 1, exportSchema = false ) abstract class AppDatabase : RoomDatabase() { abstract fun rentDao(): RentDao }
额外注意事项
- 插入数据时,需要先插入House获取返回的houseId,再给ApartmentOptions设置对应的houseId后插入,这样关联查询才能正确匹配
- 字段名尽量避免与类名重复,防止Room解析时出现歧义
内容的提问来源于stack exchange,提问作者Lulu97
相关产品推荐
相关产品推荐

