ROOM预填充数据库登录报错:查询返回列缺少id、password字段
解决Room预填充数据库登录应用的"The columns returned by the query does not have the fields [id,password]"报错
核心报错原因
你的DAO查询仅返回单个字段(email或password),但方法返回类型是Admindata实体类——该类包含id、email、password三个字段。Room无法用缺失字段的数据构建完整的实体对象,因此抛出该错误。
分步解决方案
1. 修正DAO查询逻辑
不需要分别查询邮箱和密码,直接根据邮箱查询完整的用户记录,再验证密码是否匹配。修改后的DAO代码:
@Dao interface DAO { // 根据邮箱查询完整的用户实体,返回null表示无匹配记录 @Query("SELECT * FROM admindb WHERE email = :email") suspend fun findByEmail(email: String): Admindata? }
2. 修复登录Fragment的多处逻辑问题
原代码存在变量赋值错误、异步查询未等待、验证逻辑失效等问题,修正后的代码:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.continuebutton.setOnClickListener { val email = binding.EmailSpace.text.toString().trim() val password = binding.PasswordSpace.text.toString().trim() // 统一输入验证逻辑,避免多个Toast同时弹出 when { email.isEmpty() -> { Toast.makeText(context, "Поле пустое введите email", Toast.LENGTH_SHORT).show() } password.isEmpty() -> { Toast.makeText(context, "Поле пустое введите пароль", Toast.LENGTH_SHORT).show() } password.length < 8 -> { Toast.makeText(context, "Пароль слишком короткий", Toast.LENGTH_SHORT).show() } else -> { scope.launch { // 查询数据库中对应邮箱的用户记录 val adminData = db.getDAO().findByEmail(email) // 验证密码是否匹配 val isAuthSuccess = adminData != null && adminData.password == password // 回到UI线程处理跳转或提示 requireActivity().runOnUiThread { if (isAuthSuccess) { findNavController().navigate(R.id.action_loginFragment_to_lastfragment) } else { Toast.makeText(context, "Данные введены не верно", Toast.LENGTH_SHORT).show() } } } } } } }
3. 校验预填充数据库结构
确保资产目录中的dbforpetproject.db内的admindb表包含id(主键)、email、password三个字段,且字段类型与Admindata实体类定义一致。如果预填充表缺失字段,Room同样无法正确映射实体。
额外优化建议
- 避免明文存储密码,可使用MD5、SHA-256或Android Jetpack Security进行加密存储
- 添加按钮点击防抖,防止用户重复触发请求
- 可增加加载状态提示(如ProgressBar)提升用户体验
内容的提问来源于stack exchange,提问作者user20498005
相关产品推荐
相关产品推荐

