Android Room @Embedded字段编译报错(提示无name列)问题咨询
错误原因
使用@Embedded注解修饰字段时,Room不会在对应表中生成与字段同名的独立列,而是会将嵌套类内部的所有字段直接平铺到当前实体的表中。你的示例中Name类的三个字段会直接作为userItemsEntity表的列,默认列名就是primary、sortindex、content,因此UPDATE语句里引用name列会触发不存在的报错。
解决方案
方案1:使用@Update注解(最简便)
Room原生支持直接更新整个实体对象,会自动处理所有嵌入字段的映射,不需要手写UPDATE SQL,也天然支持多层级嵌入场景:
@Update fun updateItem(item: Item)
调用时构造好完整的Item对象传入即可。
方案2:修改自定义Query的SQL和参数映射
如果确实需要手写UPDATE语句,有两种可行写法:
写法A:拆分嵌入字段为独立参数
@Query("UPDATE userItemsEntity SET " + "objecttype=:objecttype, subtype=:subtype, collid=:collid, " + "primary=:namePrimary, sortindex=:nameSortIndex, content=:nameContent " + "WHERE objectid=:objectid") fun updateItem( objecttype: String?, objectid: Int, subtype: String?, collid: Int?, namePrimary: Boolean?, nameSortIndex: Int?, nameContent: String? )
写法B:直接引用参数的内部属性(Room 2.1及以上版本支持)
不需要拆分Name类型参数,直接在SQL中访问其内部字段:
@Query("UPDATE userItemsEntity SET " + "objecttype=:objecttype, subtype=:subtype, collid=:collid, " + "primary=:name.primary, sortindex=:name.sortindex, content=:name.content " + "WHERE objectid=:objectid") fun updateItem( objecttype: String?, objectid: Int, subtype: String?, collid: Int?, name: Name? )
多层级嵌入注意事项
后续实现3层级嵌入时,建议给每层@Embedded注解加prefix参数避免字段重名,示例如下:
@Embedded(prefix = "name_") var name: Name?
添加前缀后,平铺的列名会变为name_primary、name_sortindex、name_content,手写SQL时使用对应带前缀的列名即可,多层嵌入每一层设置不同前缀就能完全避免字段冲突。
内容的提问来源于stack exchange,提问作者JPM
相关产品推荐
相关产品推荐

