2012-07-16 9 views
6

현재 Play 2.0 (스칼라)에서 플레이 중입니다. 나는 그것이 많은 재미임을 인정해야한다. 비록 데이터베이스 작업 예외와 관련된 질문이입니다.Play에서 DB 관련 예외를 관리하는 방법! 2.0/Anorm을 사용하는 스칼라

의 내가 도메인 클래스로 자동차이 나는 ​​분야 중 하나에 무결성 제약 조건을 가지고,의는 모델 그래서 그 DB에 내가 두 (2) 행을 갖는 가질 수 없습니다 가정 해 봅시다 가정 해 봅시다 나는이를 호출 할 때 다음, 나는 이전 코드에서와 같이 예외를 catch하지 않는 경우

def create(car: Car): Option[Long] = { 
    DB.withConnection { implicit connection => 
     try { 
      SQL("insert into cars (name, model) values ({name},{model}").on("name" -> car.name, "model" -> car.model).executeInsert() 
     } catch { 
      case e: Exception => { 
      Logger.debug(e.getMessage()) 
      None 
     } 
    } 
} 

: 같은 모델명 :

case class Car(id: Pk[Long], name: String, model: String) 

나는이 같은 DB에서 레코드를 삽입하는 것을 시도하고있다 방법 모델이 이미 데이터베이스에 존재하는 값을 갖는 내 컨트롤러에서 나는 다음과 같은 예외가 발생했습니다 :

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'Enzo' for key 'model' 

그래서이를 미세을 가지고 예외을 MySQLIntegrityConstraintViolationException을 잡는 대신 수있는 방법이 있나요 무엇이 잘못 될 수 있는지에 대한 세분 된 제어를 수행 한 다음 예를 들어 (브라우저 또는 모바일 장치에서) 내 사용자에게 좀 더 간결한 피드백을 제공합니까?

DB 관련 작업과 예외를 처리하는 가장 좋은 방법입니까 아니면 모두가 사용하는 모범 사례가 있습니까? 사전에

덕분에,

답변

2

난 당신이 라인에서 뭔가처럼 보이는 생각 :

import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException 

catch { 
    case e:MySQLIntegrityConstraintViolationException => Logger.debug("Whoops") 
    case e:Exception => { 
    Logger.debug(e.getMessage()) 
    None 
    } 
} 

중요가 : 당신이 com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationExceptioncom.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException을 가져, 그리고 확인하십시오. 보다 정확하게는 스택 추적에서 가져 오기가 예외와 일치하는지 확인하십시오.

베스트 프랙티스에 관해서는이 프레임 워크로도 놀고있는 것처럼 잘 모릅니다 :).

사용자에게 피드백을 보내려면 ... 플래시 스코프는 일렬 이체를 '다음 페이지'로 전달하는 좋은 방법 일 수 있습니다 (예 : 자동차가 성공적으로 저장되었는지 여부). 참조 : http://www.playframework.org/documentation/2.0/ScalaSessionFlash ('Flash scope'아래로 스크롤하십시오.)

+1

나는이 같은 MySQLIntegrityConstraintViolationException 예외를 잡으려고 시도했지만 작동하지 않습니다 : 여기 받는다는의 pom.xml에서 MySQL의 의존성 부분이다. 아마도 MySQLIntegrityConstraintViolationException은 사례 클래스가 아니기 때문에 패턴 일치에 적합하지 않기 때문일 수 있습니다. – kaffein

+1

@kaffein non-case 클래스는 잘 일치 할 수 있습니다. 예를 들어 그들을 분해 할 수 없습니다. 'case NonCaseClass (e) =>'는 기본값으로 적용되지 않는 메소드가 없으므로 수행 할 수 없습니다. 제 경우에는 문제가 잘못 가져 왔습니다. com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException 대신'com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException'을 임포트했습니다 ('jdbc4' 패키지 참고). –

1

저는 약간 다른 놀이터에서 작업하고 있지만, 이해할 수있는 한 동일한 문제를 해결했습니다. 저는 liftweb, maven 및 scala 2.9를 사용하고 있습니다.

예외는 RuntimeException으로 래핑됩니다. 그것을 잡으려고 나는 RuntimeException을 잡아서 원인을 조사했다. 제약 조건 위반 인 경우 비즈니스를 수행하고, 그렇지 않으면 예외를 던집니다. 빌드가 다음과 같은 오류가 발생하면

import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException 
... 
    } catch { 
     case e: RuntimeException => { 
     e.getCause match { 
      case cause: MySQLIntegrityConstraintViolationException => { 
      ... 
      } 
      case _ => throw e 
     } 
     } 
    } 

: 다음 코드를 참조

error: object mysql is not a member of package com 

체크 받는다는 치어에서 MySQL 패키지의 정의. 내 경우에는 런타임 범위로 정의되었습니다. 범위를 컴파일하도록 변경하면 빌드가 성공하고 런타임에이 캐치가 제대로 작동합니다.

<dependency> 
     <groupId>mysql</groupId> 
     <artifactId>mysql-connector-java</artifactId> 
     <version>5.1.18</version> 
     <scope>runtime</scope> 
    </dependency>