Is it possible to auto derive codecs for values classes in scala-mongo-driver?
Using existing macros produces StackOverflowError
package test
import org.bson.codecs.configuration.CodecRegistries.{fromCodecs, fromProviders, fromRegistries}
import org.mongodb.scala.MongoClient.DEFAULT_CODEC_REGISTRY
import org.mongodb.scala.bson.codecs.Macros._
import org.mongodb.scala.{MongoClient, MongoCollection}
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
// Models
case class Name(value: String) extends AnyVal
case class Person(name: Name)
object TestValueClassCodecs extends App {
private[this] val codecRegistry =
fromRegistries(
fromProviders(
classOf[Person],
classOf[Name],
),
DEFAULT_CODEC_REGISTRY
)
protected val collection: MongoCollection[Person] =
MongoClient(s"mongodb://localhost:27017")
.getDatabase("TestDB")
.withCodecRegistry(codecRegistry)
.getCollection[Person]("test_repo_values_classes")
val res = Await.result(
collection.insertOne(Person(Name("Jesus"))).toFuture(),
10.seconds
)
}
Output:
Caused by: java.lang.StackOverflowError
at scala.collection.LinearSeqOptimized.length(LinearSeqOptimized.scala:54)
at scala.collection.LinearSeqOptimized.length$(LinearSeqOptimized.scala:51)
at scala.collection.immutable.List.length(List.scala:91)
at scala.collection.SeqLike.size(SeqLike.scala:108)
at scala.collection.SeqLike.size$(SeqLike.scala:108)
at scala.collection.AbstractSeq.size(Seq.scala:45)
at scala.collection.convert.Wrappers$IterableWrapperTrait.size(Wrappers.scala:25)
at scala.collection.convert.Wrappers$IterableWrapperTrait.size$(Wrappers.scala:25)
at scala.collection.convert.Wrappers$SeqWrapper.size(Wrappers.scala:66)
at java.util.AbstractCollection.toArray(AbstractCollection.java:136)
at java.util.ArrayList.<init>(ArrayList.java:178)
at org.bson.internal.ProvidersCodecRegistry.<init>(ProvidersCodecRegistry.java:34)
at org.bson.codecs.configuration.CodecRegistries.fromRegistries(CodecRegistries.java:126)
at org.mongodb.scala.bson.codecs.macrocodecs.MacroCodec.$init$(MacroCodec.scala:86)
at test.TestValueClassCodecs$$anon$1$$anon$3$NameMacroCodec$1.<init>(TestValueClassCodecs.scala:51)
at test.TestValueClassCodecs$$anon$1$$anon$3$NameMacroCodec$2$.apply(TestValueClassCodecs.scala:51)
at test.TestValueClassCodecs$$anon$1$$anon$3.get(TestValueClassCodecs.scala:51)
at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:45)
at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:45)
at org.bson.internal.ChildCodecRegistry.get(ChildCodecRegistry.java:58)
at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:45)
at org.bson.internal.ChildCodecRegistry.get(ChildCodecRegistry.java:58)
at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:45)
at org.bson.internal.ChildCodecRegistry.get(ChildCodecRegistry.java:58)
at org.bson.internal.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:45)
I am using version:
org.mongodb.scala:mongo-scala-bson_2.12:4.1.1
If the Name
class is not a value one everything works just fine.