mongo-scala-driver 2.7.0 を使用して mongo db に永続化したかったのです。私のケースクラスは次のように少し見えます
case class App(
@BsonProperty("_id") id: String = "",
appName: String
createdBy: String,
createdAt: Date,
metadata: AppMetadata,
)
sealed class AppMetadata {
final val _t: String = this.getClass.getSimpleName
}
case class App1Metadata(clientId: String,
savedSearches: List[String]
) extends ScopeMetadata
case class App2Metadata(agencyId: String,
randomData: List[Int]
) extends ScopeMetadata
ご覧のとおり、アプリに対するメタデータは、アプリ (App1 と App2) によって大きく異なる場合があります。したがって、すべてのアプリで使用できる 1 つのメタデータ ケース クラスを持つことはできません。したがって、上記のように、アプリごとにメタデータのケース クラスを用意し、それらすべてを親のトレイトから拡張することにしました。これを達成するために、ここでscala mongoドライバーのドキュメントと別のstackoverflowの質問に従おうとしていました。ご覧のとおり_t
、sealed trait にフィールドを入れました。ドキュメントによると、これは Bson との間でドキュメントをデコードおよびエンコードする際のヒントとして役立つため、必須です。
これが私のコーデックの外観です
def customCodeRegistry() = {
fromProviders(
Macros.createCodecProviderIgnoreNone[App](),
Macros.createCodecProviderIgnoreNone[App1Metadata](),
Macros.createCodecProviderIgnoreNone[App2Metadata]()
)
}
val customCodecRegistry2 = CodecRegistries.fromProviders(Macros.createCodecProvider[ScopeMetadata]())
val codecRegistry = fromRegistries(customCodeRegistry(), DEFAULT_CODEC_REGISTRY,customCodecRegistry2)
私は単に使い続ける
override def addApp(app: App): Future[String] = {
for {
_ <- collection.insertOne(app).toFuture()
} yield user.id
}
mongo db に永続化されているドキュメントには、_t field
内部のメタデータ オブジェクトがありません。これは、Mongo Scala Driver が bson を適切なメタデータ ケース クラスに変換するためにドキュメントに従って必要なため、次を使用してドキュメントを取得しようとすると
override def getUser(email: String): Future[Option[User]] = {
collection.find(equal(EMAIL_FIELD, email)).headOption()
}
エラーメッセージで次のように表示されます
Could not decode sealed case class. Missing '_t' field.
ただし、_t フィールドをメタデータ オブジェクト内の mongo に、デコード先のクラスの名前で明示的に追加すると、すべてが正常に機能し、get 操作中に正しいケース クラスが取得されます。_t field
なぜ mongo insert を使用しても、が挿入されないのかわかりません