2012-07-16 13 views
6

Aktualnie gram w Play 2.0 (Scala). Muszę przyznać, że to świetna zabawa. Mam pytanie związane z operacjami bazy danych wyjątkami.Jak zarządzać wyjątkami związanymi z bazą danych w grze! 2.0/Scala za pomocą Anorma

Powiedzmy mam Car jako klasa domeny i że mam ograniczenie integralności jednej dziedzinie, powiedzmy modelu tak że w db nie mogę mieć dwa (2) wiersze o sama nazwa modelu:

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

próbuję wstawić rekord w DB takiego:

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

jeśli nie złapać wyjątek jak w poprzednim kodzie, wtedy kiedy ja nazywam to metoda z mojego kontrolera z modelu o wartości już istniejących w bazie danych, mam następujący wyjątek rzucony:

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

Czy istnieje sposób, aby złapać MySQLIntegrityConstraintViolationException zamiast wyjątek tak, że mam Precyzyjna szczegółową kontrolę nad tym, co może pójść nie tak, a następnie dostarczyć bardziej zwięzłe informacje zwrotne do mojego użytkownika na przykład (w przeglądarce lub na urządzeniu mobilnym)?

Czy jest to najlepszy sposób na obsługę operacji i wyjątków związanych z bazami danych lub czy istnieją jakieś sprawdzone metody, z których każdy korzysta?

góry dzięki,

Odpowiedz

2

myślę szukasz jak coś w tym kierunku:

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

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

Ważna uwaga: upewnij się, że import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException i nie com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException. Dokładniej, upewnij się, że import odpowiada wyjątkowi w twoim stosie śledzenia.

Co do najlepszych praktyk, nie wiem, jak również gram z tym schematem :).

Co do informacji zwrotnej dla użytkownika ... być może Flash Scope to dobry sposób na komunikowanie się z jedną linią do "następnej strony" (np. Jeśli samochód został pomyślnie zapisany lub nie). Zobacz: http://www.playframework.org/documentation/2.0/ScalaSessionFlash (Przewiń w dół do "zakresu Flash").

+1

Próbowałem złapać wyjątek MySQLIntegrityConstraintViolationException takiego, ale to nie działa. Prawdopodobnie dlatego, że MySQLIntegrityConstraintViolationException nie jest klasą przypadku, a następnie nie kwalifikuje się do dopasowania wzorców. – kaffein

+1

@kaffein klas nie-przypadkowych można dopasować po prostu dobrze, po prostu nie można ich dekonstruować, np. nie można wykonać 'case NonCaseClass (e) =>', ponieważ domyślnie nie mają one metody unapply. W moim przypadku problemem był nieprawidłowy import. Zaimportowałem 'com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException' zamiast' com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException' (zwróć uwagę na pakiet 'jdbc4'). –

1

Pracuję na nieco innym placu zabaw, ale, o ile rozumiem, rozwiązałem ten sam problem. Pracuję z liftweb, maven i scala 2.9.

Wyjątek jest zawijany za pomocą wyjątku RuntimeException. Aby go złapać, łapię RuntimeException i sprawdzam jego przyczynę. W przypadku naruszenia ograniczeń wykonuję swoją działalność, w przeciwnym razie odrzucam wyjątek. Zobacz następujący kod:

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

Jeśli kompilacja nie powiedzie się z powodu następującego błędu:

error: object mysql is not a member of package com 

sprawdzić definicję pakietu mysql na maven POM. W moim przypadku został zdefiniowany jako zasięg runtime. Zmiana go na kompilowany zakres pozwolił na powodzenie kompilacji, aw czasie wykonywania ten catch działa poprawnie. Oto mysql sekcja dependancy w maven pom.xml:

<dependency> 
     <groupId>mysql</groupId> 
     <artifactId>mysql-connector-java</artifactId> 
     <version>5.1.18</version> 
     <scope>runtime</scope> 
    </dependency> 
Powiązane problemy