Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当mongodb给出错误时,如何从salatDAO获取None选项_Mongodb_Scala_Scalatra_Salat - Fatal编程技术网

当mongodb给出错误时,如何从salatDAO获取None选项

当mongodb给出错误时,如何从salatDAO获取None选项,mongodb,scala,scalatra,salat,Mongodb,Scala,Scalatra,Salat,基本上,当插入一个新用户时,它会返回Some(“新用户的ObjectId”),这正是我所期望的。然而,当我在电子邮件上放置索引时,我会得到一个重复的键错误。我想要的不是得到重复键错误,而是像我从集合中读取并且没有匹配文档时那样得到None选项 当MongoDB返回重复密钥错误时,如何获得None选项 或者我应该如何处理返回的错误?对于这个问题,我将给出两个答案。第一个需要稍微改变你的方法。如果SalaDAO功能可能会在INSERT上抛出异常,那么您可能需要考虑更改 CuraTeals函数,以返回

基本上,当插入一个新用户时,它会返回Some(“新用户的ObjectId”),这正是我所期望的。然而,当我在电子邮件上放置索引时,我会得到一个重复的键错误。我想要的不是得到重复键错误,而是像我从集合中读取并且没有匹配文档时那样得到None选项

当MongoDB返回重复密钥错误时,如何获得None选项


或者我应该如何处理返回的错误?

对于这个问题,我将给出两个答案。第一个需要稍微改变你的方法。如果SalaDAO功能可能会在INSERT上抛出异常,那么您可能需要考虑更改<代码> CuraTeals<代码>函数,以返回<代码>尝试[选项[Objd] ] /代码>,并像这样修改:

import com.escalatesoft.subcut.inject._
import com.mongodb.casbah.Imports._
import com.novus.salat._
import com.novus.salat.global._
import com.novus.salat.dao._

case class User(_id: ObjectId = new ObjectId, email: String, password: String)

class UserDAO(coll: MongoCollection = DatabaseClient.getCollection("users")) extends SalatDAO[User, ObjectId](
  collection = coll
)

class UserRepository(implicit val bindingModule: BindingModule) extends Injectable {
  val userDAO = injectOptional [UserDAO] getOrElse {new UserDAO}

  def createUser (email: String, password: String):Option[ObjectId] = {
    val newUser = User(email = email, password = password)
    val createdUser = userDAO.insert(newUser)
    createdUser
  }
}
现在调用者知道结果将是三件事之一:成功(Some(objectId)),
成功(None)
(不确定何时会发生,但由于这是一个
选项,您必须能够处理它)或失败(包装一些异常)。这样,您甚至可以在
故障中对异常进行模式匹配,以确保它是在重复键上抛出的异常,并相应地采取行动,而不是简单地吞下任何异常并假设它一定是由于重复键引起的

现在,如果您真的希望任何故障都没有,您可以像这样重新定义
createUser

def createUser (email: String, password: String):Try[Option[ObjectId]] = {
  val newUser = User(email = email, password = password)
  Try(userDAO.insert(newUser))  
}

这将吞掉
insert
中的任何异常,并返回一个
None

我将给您两个问题的答案。第一个需要稍微改变你的方法。如果SalaDAO功能可能会在INSERT上抛出异常,那么您可能需要考虑更改<代码> CuraTeals<代码>函数,以返回<代码>尝试[选项[Objd] ] /代码>,并像这样修改:

import com.escalatesoft.subcut.inject._
import com.mongodb.casbah.Imports._
import com.novus.salat._
import com.novus.salat.global._
import com.novus.salat.dao._

case class User(_id: ObjectId = new ObjectId, email: String, password: String)

class UserDAO(coll: MongoCollection = DatabaseClient.getCollection("users")) extends SalatDAO[User, ObjectId](
  collection = coll
)

class UserRepository(implicit val bindingModule: BindingModule) extends Injectable {
  val userDAO = injectOptional [UserDAO] getOrElse {new UserDAO}

  def createUser (email: String, password: String):Option[ObjectId] = {
    val newUser = User(email = email, password = password)
    val createdUser = userDAO.insert(newUser)
    createdUser
  }
}
现在调用者知道结果将是三件事之一:成功(Some(objectId))
成功(None)
(不确定何时会发生,但由于这是一个
选项,您必须能够处理它)或失败(包装一些异常)。这样,您甚至可以在
故障中对异常进行模式匹配,以确保它是在重复键上抛出的异常,并相应地采取行动,而不是简单地吞下任何异常并假设它一定是由于重复键引起的

现在,如果您真的希望任何故障都没有,您可以像这样重新定义
createUser

def createUser (email: String, password: String):Try[Option[ObjectId]] = {
  val newUser = User(email = email, password = password)
  Try(userDAO.insert(newUser))  
}

这将吞掉
insert
中的任何异常,并返回一个
None

如果您要求电子邮件是唯一的,那么您的insert方法应该只捕获并处理DuplicateKeyError(不是所有可能的错误-如果写入完全失败怎么办?您不想知道吗?)或者先检查唯一密钥是否存在,从而完全避免此错误

我认为更好的方法不是消除错误,而是首先使用您的唯一键“email”搜索集合,如果您发现了什么,要么更新现有用户,要么忽略重复用户——不管您的用例是什么

第二,如果您将其用于单元测试,那么您的单元测试应该以这样一种方式设置和拆除测试集合,即您的每个测试用例在已知状态下与外部资源(MongoDB集合)一起运行

下面是Salat如何使用specs2实现这一点的示例:

如果您要求电子邮件是唯一的,那么您的insert方法应该只捕获并处理DuplicateKeyError(不是所有可能的错误-如果写入完全失败怎么办?您不想知道吗?),或者通过先检查唯一密钥是否存在来完全避免此错误

我认为更好的方法不是消除错误,而是首先使用您的唯一键“email”搜索集合,如果您发现了什么,要么更新现有用户,要么忽略重复用户——不管您的用例是什么

第二,如果您将其用于单元测试,那么您的单元测试应该以这样一种方式设置和拆除测试集合,即您的每个测试用例在已知状态下与外部资源(MongoDB集合)一起运行

下面是Salat如何使用specs2实现这一点的示例: