2013-07-10 3 views
0
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 
    } 
} 

기본적으로 새 사용자를 삽입하면 정확히 예상 한 일부 ("새 사용자의 ObjectId")가 반환됩니다. 그러나 색인에 이메일을 넣으면 중복 키 오류가 발생합니다. 내가 원하는 것은 중복 키 오류를받는 대신 None 옵션을 얻는 것입니다. 컬렉션에서 읽었을 때처럼 일치하는 문서가없는 것과 같습니다.어떻게 얻을 수 없음 mongodb에서 오류가 발생했을 때 salatDAO의 옵션

MongoDB에서 중복 키 오류를 반환하면 없음 옵션을 어떻게 얻을 수 있습니까?

또는 내가이 오류를 어떻게 처리해야합니까?

답변

1

이 문제에 대한 두 가지 답변을 제공해 드리겠습니다. 첫 번째 방법은 약간의 변경을 요구합니다.

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

이제 호출자가 결과 중 하나가 될 것을 알고 다음 Salat DAO 기능이 잠재적으로 삽입에 대한 예외를 던지는 경우, 대신 Try[Option[ObjectId]]을 반환 등처럼 재 작업하는 createUser 기능을 변경하는 것을 고려할 수 있습니다 세 가지 : Success(Some(objectId)), Success(None) (이것이 언제 발생할지 모르지만 Option이므로 처리 할 수 ​​있어야 함) 또는 일부 예외를 래핑하는 Failure. 이 방법을 사용하면 Failure의 예외를 패턴 매치하여 중복 키에 던져진 것인지 확인하고 예외를 삼키지 않고 복제 키로 인해야만한다고 가정 할 수 있습니다.

이제 당신이 정말로 어떤 실패에 대한 없음을 원하지 않는 경우, 당신은이 같은 createUser을 다시 정의 할 수 있습니다 :

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

insert에서 예외를 삼키는하고 None를 반환합니다.

2

전자 메일이 고유해야하는 경우 삽입 메서드는 DuplicateKeyError를 잡아서 처리해야합니다 (생각할 수있는 모든 오류가있는 것은 아닙니다 - 쓰기가 완전히 실패한 경우, 알고 싶지 않습니까?) 이 오류는 전적으로 고유 키가 먼저 있는지 확인하여 검사합니다.

더 나은 방법은 오류를 음소거하는 것이 아니라 고유 한 키 "이메일"을 사용하여 컬렉션을 먼저 검색하고 무언가를 찾으면 기존 사용자를 업데이트하거나 중복 된 사용자를 무시하는 것입니다. 유스 케이스가 있습니다.

두 번째로, 단위 테스트를 위해 이것을 사용한다면, 유닛 테스트는 각 테스트 케이스가 설정되어 있고, 각 테스트 케이스가 외부 리소스 (MongoDB 컬렉션)와 함께 실행되도록해야한다. 알려진 상태.

다음은 Salat이 specs2를 사용하여 수행하는 방법의 예입니다. https://github.com/novus/salat/blob/master/salat-core/src/test/scala/com/novus/salat/test/dao/SalatDAOSpec.scala