Android Room报错:Entities and POJOs必须拥有可用的公共构造函数——JSON解析数据类存入Room数据库问题求助
解决Room报错:Entities and POJOs must have a usable public constructor
这个问题的核心原因有两个:一是你给被@Embedded注解的类错误添加了@Entity注解,二是Room对Kotlin数据类的构造函数解析需要符合特定规则。下面是分步解决方法:
1. 移除内嵌类的@Entity注解
Byline、Multimedia、Headline这些类是被Docs通过@Embedded内嵌的字段,它们不是独立的数据库表,不需要添加@Entity注解。保留@Entity会让Room将它们识别为独立实体,进而导致构造函数解析冲突。修改后的代码如下:
// 仅作为数据类,无需@Entity data class Byline( val original: String ) data class Multimedia( val url: String ) data class Headline( val main: String )
2. 调整Docs实体类的构造函数
Room要求实体类必须有一个Room能识别的公共构造函数。对于自增主键,建议将默认值从null改为0(Room会自动将0替换为生成的主键值,避免null带来的解析问题)。同时如果需要,可以显式添加一个不含主键的构造函数,供Room插入数据时使用:
@Entity(tableName = "docs") data class Docs( @PrimaryKey(autoGenerate = true) var id: Int = 0, // 用0作为自增主键默认值 val _id: String, val `abstract`: String, @Embedded val byline: Byline, val document_type: String, @Embedded val multimedia: Multimedia, @Embedded val headline: Headline, val lead_paragraph: String, val news_desk: String, val pub_date: String, val section_name: String, val snippet: String, val source: String, val subsection_name: String, val type_of_material: String, val uri: String, val web_url: String, val word_count: Int ) { // 显式添加不含主键的构造函数,供Room插入时调用 constructor( _id: String, `abstract`: String, byline: Byline, document_type: String, multimedia: Multimedia, headline: Headline, lead_paragraph: String, news_desk: String, pub_date: String, section_name: String, snippet: String, source: String, subsection_name: String, type_of_material: String, uri: String, web_url: String, word_count: Int ) : this(0, _id, `abstract`, byline, document_type, multimedia, headline, lead_paragraph, news_desk, pub_date, section_name, snippet, source, subsection_name, type_of_material, uri, web_url, word_count) }
3. 额外检查点
- 确保你的Room依赖使用的是稳定版,避免版本兼容问题;
- 确认所有字段的名称和类型在构造函数中完全匹配(Kotlin数据类默认会生成匹配的构造函数,但显式声明可以避免潜在问题);
- 对于关键字字段(比如
abstract),用反引号包裹的方式是正确的,Room可以正常识别。
内容的提问来源于stack exchange,提问作者Adrian Prawira
相关产品推荐
相关产品推荐

