【发布时间】:2018-01-24 06:48:31
【问题描述】:
我看到隐式类的一些意外行为。我有一个从 Mongo 检索的案例类,并且在某些情况下包装到一个隐式类中,该类具有方便的惰性 val 以从其他相关集合中检索数据。代码看起来像
case class MyClass(
_id: UUID, ...,
//some fields
)
然后
object MyImplicits {
implicit class MyRichClass(c: MyClass){
lazy val field1: Future[Iterable[T1]] = db.findAll[T1](bson)
lazy val field2: Future[Iterable[T2]] = db.findAll[T2](bson)
}
}
并且转换使用像
import ...MyImplicits.MyRichClass
val c: MyClass...
c.field1.map(...)
我的问题是 field1 和 field2 中的 Futures 总是包含一个空的 Iterable。我今天大部分时间都在调试我的查询,它们在测试代码和 Mongo cli 中都能正常工作。
任何提示将不胜感激。
我有一个 org.mongodb.scala.MongoClient 的包装器,它有:
/**
* Finds all instances of T using raw mongo query
*
* @param bson search query
* @tparam T
* @return
*/
private[service] def findAll[T: ClassTag](bson: Bson): Future[Iterable[T]] = {
val colName = resolveCollection[T]
logger.info("colName = " + colName)
db.getCollection[T](colName).find(equal("ownerId", "user1")).toFuture().map(t => {
logger.info("t = " + t)
t
})
}
/**
* Returns collection name for given type
* @tparam T
* @return
*/
private def resolveCollection[T: ClassTag]: String = {
scala.reflect.classTag[T] match {
case `...tag` => "collectionName"
....
}
}
equal("ownerId", "user1")
为调试目的以及额外的记录器进行了硬编码。
【问题讨论】:
-
只是为了确保您的
MyClass没有field1字段,对吧? -
不,它没有。
-
魔鬼在细节中,你错过了所有重要的。您将需要共享一个包含有关某些示例类的完整详细信息的最小实现。您究竟是如何做到“一些 mongo 查询”是最重要的。
-
@SarveshKumarSingh 我已经更新了问题
-
使用
lazy val作为字段来懒惰地从数据库中加载数据听起来像是给我带来很多麻烦的来源。它在作为类字段的微不足道的东西中隐藏了很多细节。