The documentation describes using the magnet pattern to get implicit conversion to BSON types. See on this page http://mongodb.github.io/mongo-java-driver/4.1/driver-scala/bson/scala-documents/. I have tried defining an implicit object that extends BsonTransformer, but it fails to find a codec for the type. Am I missing something / has someone got this working? Sample code below, assume the insert method is being called.
case class CustomType(specialString: String)
implicit object TransformCustomType extends BsonTransformer[CustomType] {
def apply(value: CustomType): BsonString =
BsonString(value.specialString)
}
lazy val db: MongoDatabase = client.getDatabase(dbName).withCodecRegistry(DEFAULT_CODEC_REGISTRY)
lazy val testCollection: MongoCollection[CustomType] = db.getCollection[CustomType](collectionName)
def insert: Future[Completed] = testCollection.insertOne(CustomType("a")).toFuture
Error - org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.bla.BlaClass$CustomType.
*note that I am aware this can be done with
val codecRegistry = fromRegistries(fromProviders(classOf[CustomType]))
but I am just using this example to ask to learn the magnet pattern for a messier case.
If there is an implicit BsonTransformer[T]
(instance of type class BsonTransformer
) in a scope then there are implicit conversions
T => CanBeBsonValue
(CanBeBsonValue
is a wrapper over BsonValue
),
(String, T) => CanBeBsonElement
(CanBeBsonElement
is a wrapper over BsonElement
, which is a "tuple" of String
and BsonValue
),
Iterable[(String, T)] => CanBeBsonElements
(CanBeBsonElements
is a wrapper over Iterable[BsonElement]
)
defined in BsonMagnets
(CanBeBsonValue
, CanBeBsonElement
, CanBeBsonElements
are magnets 1 2).
Then Document
can be created via factory methods
def apply(elems: CanBeBsonElement*): Document
def apply(elem: CanBeBsonElements): Document
So try
val doc = Document("a" -> CustomType("bb"))
val testCollection: MongoCollection[Document] = ???
testCollection.insertOne(doc)