2012-07-16 35 views
6

我目前在Play!ing玩Play 2.0(Scala)。我必須承認這很有趣。我有一個問題,雖然有關數據庫操作異常如何管理Play中與數據庫相關的異常! 2.0/Scala使用Anorm

比方說,我有汽車爲域類和我在球場上的一個完整性約束,讓我們假設模式,這樣在DB我不能有兩個(2)行具有同一型號名稱:

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

我試圖插入這樣一個數據庫中的記錄:

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,而不是異常讓我有一個細(例如,在瀏覽器中或在移動設備上)對可能出錯的內容進行嚴格控制,然後向我的用戶提供更簡潔的反饋?

這是處理與數據庫相關的操作和異常的最佳方式,還是有任何人人都使用的最佳做法?

在此先感謝,

回答

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.jdbc4.MySQLIntegrityConstraintViolationException,而不是com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException。更確切地說,請確保您的導入與堆棧跟蹤中的異常匹配。

至於最佳做法,我不知道我也玩這個框架:)。

至於給用戶的反饋......也許Flash Scope是一種將單線傳遞給「下一頁」的好方法(例如,如果汽車被成功存儲或不存儲)。見:http://www.playframework.org/documentation/2.0/ScalaSessionFlash(向下滾動到'Flash scope')

+1

我試圖抓住MySQLIntegrityConstraintViolationException例外,像這樣的,但它無法正常工作。可能是因爲MySQLIntegrityConstraintViolationException不是案例類,因此不適合進行模式匹配。 – kaffein 2012-07-17 09:57:36

+1

@kaffein非案例類可以很好地匹配,你不能解構它們,例如你不能'NonCaseClass(e)=>',因爲它們默認情況下沒有unapply方法。在我的情況下,問題是一個不正確的導入。我導入了'com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException'而不是'com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException'(注意''jdbc4'包)。 – 2016-05-30 16:16:46

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軟件包的Maven的POM定義。在我的情況下,它被定義爲運行時範圍。將其更改爲編譯範圍允許構建成功,並且在運行時此捕獲工作正常。 下面是行家的pom.xml mysql的扶養部分:

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