无法将Mongo Scala驱动程序与案例类一起使用

时间:2018-02-01 22:13:23

标签: mongodb scala

我尝试将Scala mongo驱动程序与案例类一起使用,如下所述:http://mongodb.github.io/mongo-scala-driver/2.2/getting-started/quick-tour-case-classes/

但是我得到了例外:

Can't find a codec for class com.foo.model.User$. org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.foo.model.User$.

当我尝试插入项目时。

案例类:

case class User(
               _id: ObjectId,
                foo: String = "",
                foo2: String = "", 
                foo3: String = "",
                first: String,
                last: String,
                username: String,
                pwHash: String = ""
                gender: String,
                isFoo: Boolean = false)
extends FooTrait

代码:

val providers = fromProviders( classOf[User])

val registry = fromRegistries(providers, DEFAULT_CODEC_REGISTRY)

val connStr = "mongodb://...."

val clusterSettings = ClusterSettings.builder().applyConnectionString(new ConnectionString(connStr)).build()
        val clientSettings = MongoClientSettings.builder().codecRegistry(getCodecRegistry).clusterSettings(clusterSettings).build()

val client = MongoClient( clientSettings )
val database: MongoDatabase = client.getDatabase(dbName).withCodecRegistry(registry)

val modelCollection: MongoCollection[User] = db.getCollection("user")

val item = User(.....) //snipped
modelCollection.insertOne(item).toFuture()

完整堆栈跟踪:

Can't find a codec for class com.foo.model.User$.
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.foo.model.User$.
    at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
    at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
    at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:37)
    at com.mongodb.async.client.MongoCollectionImpl.getCodec(MongoCollectionImpl.java:1170)
    at com.mongodb.async.client.MongoCollectionImpl.getCodec(MongoCollectionImpl.java:1166)
    at com.mongodb.async.client.MongoCollectionImpl.executeInsertOne(MongoCollectionImpl.java:519)
    at com.mongodb.async.client.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:501)
    at com.mongodb.async.client.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:496)
    at org.mongodb.scala.MongoCollection.$anonfun$insertOne$1(MongoCollection.scala:410)
    at org.mongodb.scala.MongoCollection.$anonfun$insertOne$1$adapted(MongoCollection.scala:410)
    at org.mongodb.scala.internal.ObservableHelper$$anon$2.apply(ObservableHelper.scala:42)
    at org.mongodb.scala.internal.ObservableHelper$$anon$2.apply(ObservableHelper.scala:40)
    at com.mongodb.async.client.SingleResultCallbackSubscription.requestInitialData(SingleResultCallbackSubscription.java:38)
    at com.mongodb.async.client.AbstractSubscription.tryRequestInitialData(AbstractSubscription.java:151)
    at com.mongodb.async.client.AbstractSubscription.request(AbstractSubscription.java:82)
    at org.mongodb.scala.ObservableImplicits$BoxedSubscription.request(ObservableImplicits.scala:474)
    at org.mongodb.scala.ObservableImplicits$ScalaObservable$$anon$2.onSubscribe(ObservableImplicits.scala:373)
    at org.mongodb.scala.ObservableImplicits$ToSingleObservable$$anon$3.onSubscribe(ObservableImplicits.scala:440)
    at org.mongodb.scala.Observer.onSubscribe(Observer.scala:85)
    at org.mongodb.scala.Observer.onSubscribe$(Observer.scala:85)
    at org.mongodb.scala.ObservableImplicits$ToSingleObservable$$anon$3.onSubscribe(ObservableImplicits.scala:432)
    at com.mongodb.async.client.SingleResultCallbackSubscription.<init>(SingleResultCallbackSubscription.java:33)
    at com.mongodb.async.client.Observables$2.subscribe(Observables.java:76)
    at org.mongodb.scala.ObservableImplicits$BoxedObservable.subscribe(ObservableImplicits.scala:458)
    at org.mongodb.scala.ObservableImplicits$ToSingleObservable.subscribe(ObservableImplicits.scala:432)
    at org.mongodb.scala.ObservableImplicits$ScalaObservable.headOption(ObservableImplicits.scala:365)
    at org.mongodb.scala.ObservableImplicits$ScalaObservable.head(ObservableImplicits.scala:351)
    at org.mongodb.scala.ObservableImplicits$ScalaSingleObservable.toFuture(ObservableImplicits.scala:410)

我认为我做的一切都是正确的 - 除非这是一个错误,否则代码应该可行。我的mongo-scala-driver版本为2.2.0

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

以下是使用Mongo 3.6.1在我的本地方框上工作的示例。

// ammonite script mongo.sc
import $ivy.`org.mongodb.scala::mongo-scala-driver:2.2.0`

import org.mongodb.scala._
import org.mongodb.scala.connection._
import org.mongodb.scala.bson.ObjectId
import org.mongodb.scala.bson.codecs.Macros._
import org.mongodb.scala.bson.codecs.DEFAULT_CODEC_REGISTRY
import org.bson.codecs.configuration.CodecRegistries.{fromRegistries, fromProviders}

trait FooTrait

case class User(_id: ObjectId,
                foo: String = "",
                foo2: String = "",
                foo3: String = "",
                first: String,
                last: String,
                username: String,
                pwHash: String = "",
                gender: String,
                isFoo: Boolean = false) extends FooTrait

val codecRegistry = fromRegistries(fromProviders(classOf[User]), DEFAULT_CODEC_REGISTRY )

import scala.collection.JavaConverters._
val clusterSettings: ClusterSettings = ClusterSettings.builder().hosts(List(new ServerAddress("localhost")).asJava).build()
val settings: MongoClientSettings = MongoClientSettings.builder().clusterSettings(clusterSettings).build()
val mongoClient: MongoClient = MongoClient(settings)

val database: MongoDatabase = mongoClient.getDatabase("mydb").withCodecRegistry(codecRegistry)
val userCollection: MongoCollection[User] = database.getCollection("user")

val user:User = User(new ObjectId(), "foo", "foo2", "foo3", "first", "last", "username", "pwHash", "gender", true)

import scala.concurrent.duration._
import scala.concurrent.Await
// wait for Mongo to complete insert operation
Await.result(userCollection.insertOne(user).toFuture(),3.seconds)

将此代码段保存到文件mongo.sc后,您可以使用

Ammonite运行该代码段
amm mongo.sc

如果mongo在默认端口上运行,则应自动创建mydb数据库,包括新的user集合。