2012-07-16 21 views
6

私は現在Play 2.0(Scala)で再生しています。私はそれがとても楽しいと認めなければなりません。私はデータベース操作の例外に関連する質問があります。PlayでDB関連の例外を管理する方法! 2.0/Scala with Anorm

デシベルに私が有する二つの(2)の行を持つことができないようにのは、モデルを言わせて、の私は、ドメインクラスとして、私は、フィールドのいずれかに整合性制約を持っていることをカーを持っているとしましょう同じモデル名:

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

私はこのようなDBのレコードを挿入しようとしています:

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 
     } 
    } 
} 

私はこれを呼び出すときに、私はその後、前のコードのように、例外をキャッチしない場合方法すでにデータベース内の既存の値を持つモデルと私のコントローラから、私がスローされた次の例外があります。

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をインポートし、ではないことを確認してください。より正確には、インポートがスタックトレースの例外と一致することを確認してください。

ベストプラクティスに関しては、私もこのフレームワークで遊んでいると知りません:)。

ユーザーへのフィードバックとしては、Flashスコープはワンライナーを「次のページ」(たとえば、車が正常に格納されたかどうかなど)に伝えるよい方法です。参照:http://www.playframework.org/documentation/2.0/ScalaSessionFlash(「Flash scope」までスクロールしてください)

+1

私はこのようなMySQLIntegrityConstraintViolationException例外をキャッチしようとしたが、それが動作していない: ここではMavenののpom.xmlでのMySQLの依存セクションがあります。おそらく、MySQLIntegrityConstraintViolationExceptionは大文字小文字のクラスではなく、パターンマッチングに適さないからです。 – kaffein

+1

@kaffeinの非大文字小文字のクラスは、ちょうどいいところで照合することができます。 'case NonCaseClass(e)=>'を実行することはできません。なぜなら、デフォルトでは未適用メソッドがないからです。私の場合、問題は誤ったインポートでした。私は、 'com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException'(' jdbc4'パッケージに注意)の代わりに 'com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException'をインポートしました。 –

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 

のMaven POM上のMySQLパッケージの定義を確認してください。私の場合、ランタイムスコープとして定義されていました。スコープをコンパイルするように変更すると、ビルドが成功し、実行時にこのキャッチが正しく機能しています。

<dependency> 
     <groupId>mysql</groupId> 
     <artifactId>mysql-connector-java</artifactId> 
     <version>5.1.18</version> 
     <scope>runtime</scope> 
    </dependency> 
関連する問題