2

I am trying to run this simple code, which insert a document to "reports" collection under transaction.

This is the code:

def runWithTransaction(): Future[Unit] = {
    for {
      dbWithSession <- db.db.startSession()
      dbWithTx <- dbWithSession.startTransaction(None)

      reportsCollection = dbWithTx.collection[JSONCollection]("reports")
      _ <- reportsCollection.insert.one(BSONDocument("id" -> "123123"))

      _ <- dbWithTx.commitTransaction()
      _ <- dbWithSession.endSession()
    } yield ()
  }

I am getting the following error:

play.api.libs.json.JsResultException: JsResultException(errors:List((,List(JsonValidationError(List(CommandError[code=14, errmsg=BSON field 'OperationSessionInfo.txnNumber' is the wrong type 'int', expected type 'long', doc: {"operationTime":{"$time":1573135213,"$i":1,"$timestamp":{"t":1573135213,"i":1}},"ok":0,"errmsg":"BSON field 'OperationSessionInfo.txnNumber' is the wrong type 'int', expected type 'long'","code":14,"codeName":"TypeMismatch","$clusterTime":{"clusterTime":{"$time":1573135213,"$i":1,"$timestamp":{"t":1573135213,"i":1}},"signature":{"hash":{"$binary":"0000000000000000000000000000000000000000","$type":"00"},"keyId":0}}}]),WrappedArray())))))
    at reactivemongo.play.json.JSONSerializationPack$.deserialize(JSONSerializationPack.scala:61)
    at reactivemongo.play.json.JSONSerializationPack$.deserialize(JSONSerializationPack.scala:33)
    at reactivemongo.api.commands.Command$$anon$2.$anonfun$one$6(commands.scala:141)
    at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:658)
    at scala.util.Success.$anonfun$map$1(Try.scala:255)
    at scala.util.Success.map(Try.scala:213)
    at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
    at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:33)
    at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:33)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:92)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
    at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:85)
    at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:92)
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:41)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:49)
    at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

I am using:

  • scala 2.12
  • "org.reactivemongo" % "play2-reactivemongo_2.12" % "0.18.8-play27"
  • MongoDB version 4.2.1 (its actually a replica set with 1 primary)

Any help is appreciated, thanks.

cchantep
  • 9,118
  • 3
  • 30
  • 41
Ameen
  • 137
  • 3
  • Why using `JSONCollection` with BSON document? – cchantep Nov 07 '19 at 18:17
  • 1
    For anyone running across the same issue the answer (for me) is in the comment above (i.e. use BSONCollection in place of JSONCollection). Not sure why transactions blow up with stacktrace shown in OP's question when using JSONCollection, but switching to BSONCollection solved it. – virtualeyes Nov 22 '20 at 15:37
  • @virtualeyes right this is how I fixed it, thanks. – Ameen Nov 22 '20 at 16:18

1 Answers1

0

Use this code to Insert:

def insert(coll: BSONCollection, document: BSONDocument): Future[Unit] = {
    val writeRes: Future[WriteResult] = coll.insert.one(document)
    writeRes.onComplete { // Dummy callbacks
      case Failure(e) => e.printStackTrace()
      case Success(writeResult) =>
        println(s"successfully inserted document with result: $writeResult")
    }
    writeRes.map(_ => {}) // in this example, do nothing with the success
  }

And If you want to update, use this:

def update(collection: BSONCollection, item_id: Long, modifier: BSONDocument) = {
    val selector = BSONDocument("_id" -> item_id)
    println("selector ===" + selector)

    val futureUpdate = collection.update.one(
      q = selector, u = modifier,
      upsert = true, multi = false)

    futureUpdate.onComplete { // Dummy callbacks
      case Failure(e) => e.printStackTrace()
      case Success(writeResult) =>
        println(s"successfully updated document with result: $writeResult")
    }

  }
swapnil shashank
  • 877
  • 8
  • 11