You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Play与ReactiveMongo依赖后出现类型不匹配错误求助

解决ReactiveMongo升级后BSONDocument类型不匹配问题

你遇到的错误核心是类型不匹配:升级后的ReactiveMongo版本对类型检查更严格了,BSONDocument的元素要求是(String, BSONValue)类型,但你传入的Json.toJson(ZonedDateTime.now())返回的是JsValue,两者无法直接兼容——之前的版本可能有宽松的隐式转换,但新版本已经调整了这个逻辑。

先回顾你碰到的具体错误:

found : (String, play.api.libs.json.JsValue) 
[error] required: reactivemongo.bson.Producer[reactivemongo.bson.BSONElement] 
[error] (which expands to) reactivemongo.bson.Producer[(String, reactivemongo.bson.BSONValue)] 
[error] Error occurred in an application involving default arguments. 
[error] claimsCollection.update(BSONDocument("id" -> claimId), BSONDocument("$set" -> BSONDocument("status"-> "Approved" , "updationDate" -> Json.toJson(ZonedDateTime.now())))) 

结合你使用JSONCollection的代码场景,这里有两个简洁的解决方案:


方案一:改用Play JSON的JsObject构建更新语句

JSONCollection本身就是为了和Play的JSON API无缝协作设计的,直接用JsObject替代BSONDocument,就能自动利用ReactiveMongo提供的JSON-BSON隐式转换,完全避免手动类型转换的麻烦:

修改你的approveClaim方法:

def approveClaim(claimId:String)(implicit ec :ExecutionContext): Future[WriteResult] = {
  claimsCollection.update(
    Json.obj("id" -> claimId),
    Json.obj("$set" -> Json.obj(
      "status"-> "Approved",
      "updationDate" -> Json.toJson(ZonedDateTime.now())
    ))
  )
}

注意:Play默认不支持ZonedDateTime的JSON序列化,你需要先定义对应的格式器,可以添加在代码的合适位置:

import play.api.libs.json._
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter

// 定义ZonedDateTime的JSON读写规则
implicit val zonedDateTimeFormat: Format[ZonedDateTime] = Format(
  Reads[ZonedDateTime](js =>
    js.validate[String].map(str => ZonedDateTime.parse(str, DateTimeFormatter.ISO_ZONED_DATE_TIME))
  ),
  Writes[ZonedDateTime](dt =>
    JsString(dt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME))
  )
)

方案二:手动将JsValue转换为BSONValue

如果你坚持要使用BSONDocument,可以利用你已经导入的ImplicitBSONHandlers._隐式转换,把JsValue转成BSONValue:

修改后的方法:

def approveClaim(claimId:String)(implicit ec :ExecutionContext): Future[WriteResult] = {
  // 借助隐式转换自动将JsValue转为BSONValue
  val updationDateBson: BSONValue = Json.toJson(ZonedDateTime.now())
  
  claimsCollection.update(
    BSONDocument("id" -> claimId),
    BSONDocument("$set" -> BSONDocument(
      "status"-> "Approved",
      "updationDate" -> updationDateBson
    ))
  )
}

同样,这个方案也需要你先定义好ZonedDateTime的JSON格式器,否则Json.toJson(ZonedDateTime.now())会报错。


个人更推荐方案一,因为它更符合JSONCollection的设计初衷,代码更简洁,也能减少后续维护时的类型问题。

内容的提问来源于stack exchange,提问作者Manoj S Ramaswamy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:28:14