Android Room @RewriteQueriesToDropUnusedColumns 失效问题排查
解决Room多表关联查询中未使用列的报错问题
你的问题根源在于子查询返回了未被实体类映射的max(gmt_create)列,且Room 2.5.0版本中@RewriteQueriesToDropUnusedColumns注解对子查询的处理存在偶现bug,导致注解失效。以下是几种可靠的解决方式:
方案一:优化查询逻辑,避免生成多余列
既然你的目标是获取每个Work对应的最新WorkLog,可改用关联子查询直接定位最新日志行,无需额外选择max(gmt_create)列:
@Query(""" SELECT t1.*, t2.* FROM t_work t1 INNER JOIN t_work_log t2 ON t1.id = t2.work_id WHERE t2.gmt_create = ( SELECT MAX(gmt_create) FROM t_work_log WHERE work_id = t1.id ) """) fun getWorkAndLog(): Flow<Map<Work, WorkLog>>
这种写法直接通过子查询匹配最新的日志时间,返回的列完全对应Work和WorkLog实体,不会触发Room的列匹配报错。
方案二:重构子查询,分离聚合逻辑与实体列
如果偏好使用分组查询的写法,可将聚合逻辑和实体列查询分离,避免返回多余列:
@Query(""" SELECT t1.*, t3.* FROM t_work t1 INNER JOIN ( SELECT work_id, MAX(gmt_create) as latest_time FROM t_work_log GROUP BY work_id ) t2 ON t1.id = t2.work_id INNER JOIN t_work_log t3 ON t2.work_id = t3.work_id AND t2.latest_time = t3.gmt_create """) fun getWorkAndLog(): Flow<Map<Work, WorkLog>>
这里子查询仅返回work_id和最新时间,再通过关联t_work_log获取完整的日志行,最终返回的列均能被实体类映射。
方案三:修复@RewriteQueriesToDropUnusedColumns偶现失效问题
若坚持使用原查询写法,可通过以下操作解决注解偶尔失效的问题:
- 清理构建缓存:执行
Build -> Clean Project,再执行Build -> Rebuild Project,彻底清除kapt生成的临时文件; - 升级Room版本:Room 2.5.0存在注解处理器的已知bug,升级至2.6.0及以上版本可修复子查询场景下的注解失效问题,修改依赖版本后同步项目即可。
内容的提问来源于stack exchange,提问作者SageJustus
相关产品推荐
相关产品推荐

