readStartDocument仅能在CurrentBSONType为DOCUMENT而非STRING时调用错误怎么解决
错误根因
你遇到的报错是因为Spring Data MongoDB中@Query注解默认用于查询操作,期望返回BSON文档结构,而你用它执行更新语句时,Mongo返回的是更新操作的状态值(字符串类型的执行结果),类型不匹配触发了该错误。另外你当前的@Query写的是SQL语法,不兼容MongoDB的查询规则,也是问题诱因之一。
修复方案
方案1:修改Repository的注解和查询语法
给你的logout方法加上@Modifying注解声明这是修改操作,同时调整@Query为MongoDB兼容的语法:
import org.springframework.data.mongodb.repository.Modifying; import org.springframework.transaction.annotation.Transactional; public interface TokensRepository extends MongoRepository<Tokens, String> { @Modifying @Transactional @Query(value = "{ '_id' : :userId }", update = "{ $set : { 'token' : :token } }") void logout(@Param("userId") String userId, @Param("token") String token); }
注意:
@Modifying必须加,用于通知Spring Data这是写操作,不需要封装返回的文档结构- MongoDB的更新语法不支持SQL风格的update写法,要用value指定匹配条件,update指定更新动作
- 加上
@Transactional保证更新操作的事务性,避免部分更新的异常情况
方案2:用MongoRepository原生方法实现(更稳妥,语法出错概率低)
不用自定义@Query,直接通过先查后改的方式实现逻辑:
// Service层的logout方法调整为: public void logout(String userId){ try { Optional<Tokens> tokensOpt = tokensRepository.findById(userId); if(tokensOpt.isPresent()){ Tokens tokens = tokensOpt.get(); tokens.setToken(""); tokensRepository.save(tokens); } } catch (Exception e) { System.out.println(e.getMessage()); } }
这种写法利用Spring Data MongoDB自带的CRUD方法实现,不需要手动写更新语句,适配性更强。
额外校验点
- 确认接口请求的JSON格式正确,
userId是字符串类型,不是嵌套对象,避免Controller层接收参数时出现类型转换异常 - 确认你的
Tokens实体类的_id字段类型和传入的userId类型匹配,均为String类型
内容的提问来源于stack exchange,提问作者Oya
相关产品推荐
相关产品推荐

