6

私は現在、Play 2.0 (Scala) で Play!ing を行っています。とても楽しいことだと認めざるを得ません。データベース操作の例外に関する質問があります。

ドメインクラスとしてCarがあり、フィールドの1つに整合性制約があるとしましょう。モデルを言って、データベースで同じモデル名を持つ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'

Exceptionの代わりにMySQLIntegrityConstraintViolationExceptionをキャッチして、何がうまくいかないかをきめ細かく制御し、たとえば (ブラウザーまたはモバイル デバイスで) ユーザーにより簡潔なフィードバックを提供する方法はありますか?

これは、DB 関連の操作と例外を処理するための最良の方法ですか、それとも誰もが使用するベスト プラクティスはありますか?

前もって感謝します、

4

2 に答える 2

3

私はあなたがこれらの線の中で何かのように見えていると思います:

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

ベストプラクティスについては、このフレームワークでも遊んでいるのでわかりません:)。

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

于 2012-07-17T09:24:15.157 に答える
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 パッケージの定義を確認してください。私の場合、ランタイムスコープとして定義されていました。スコープをコンパイルするように変更すると、ビルドが成功し、実行時にこのキャッチが適切に機能します。maven pom.xml の mysql 依存関係セクションは次のとおりです。

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.18</version>
        <scope>runtime</scope>
    </dependency>
于 2012-11-05T08:52:54.230 に答える