2012-07-16 35 views
6

Actualmente estoy jugando con Play 2.0 (Scala). Debo admitir que es muy divertido. Tengo una pregunta relacionada con excepciones de operaciones de base de datos.Cómo administrar las excepciones relacionadas con DB en Play! 2.0/Scala usando Anorm

Digamos que tengo coche como una clase de dominio y que tengo una restricción de integridad en uno de los campos, digamos que el modelo dede manera que en el PP no puede tener dos (2) filas que tienen la mismo nombre de modelo:

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

estoy tratando de insertar un registro en la base de datos de esta manera:

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

si no detectar la excepción al igual que en el código anterior, a continuación, cuando llamo a este método de mi controlador con el modelo que tiene un valor que ya existe en la base de datos, he tirado la siguiente excepción:

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

¿Hay una manera de coger el MySQLIntegrityConstraintViolationException en lugar de Excepción por lo que tengo una fina gran control sobre lo que puede salir mal y, a continuación, proporcionar una retroalimentación más concisa a mi usuario, por ejemplo (en un navegador o en un dispositivo móvil)?

¿Es esta la mejor manera de manejar operaciones y excepciones relacionadas con bases de datos o hay alguna de las mejores prácticas que todos utilicen?

gracias de antemano,

Respuesta

2

creo que busca como algo dentro de estas líneas:

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

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

Nota importante: asegúrese de importar com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException, y no com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException. Más precisamente, asegúrese de que su importación coincida con la excepción en su rastro de pila.

En cuanto a las mejores prácticas, no sé, ya que también estoy jugando con este marco :).

En cuanto a la retroalimentación para el usuario ... tal vez el Flash Scope es una buena forma de comunicar frases sueltas a la 'página siguiente' (por ejemplo, si el auto se guardó correctamente o no). Ver: http://www.playframework.org/documentation/2.0/ScalaSessionFlash (Desplácese hasta 'Alcance del flash')

+1

Traté de capturar la excepción MySQLIntegrityConstraintViolationException como este, pero no está funcionando. Probablemente porque MySQLIntegrityConstraintViolationException no es una clase de caso y no es elegible para la coincidencia de patrones. – kaffein

+1

@kaffein las clases sin mayúsculas y minúsculas se pueden combinar muy bien, simplemente no puede deconstruirlas, p. no se puede hacer 'case NonCaseClass (e) =>', porque no tienen un método de aplicación por defecto. En mi caso, el problema fue una importación incorrecta. Importé 'com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException' en lugar de' com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException' (tenga en cuenta el paquete 'jdbc4'). –

1

Estoy trabajando en un patio de recreo un poco diferente pero, por lo que yo entiendo, he resuelto el mismo problema. Estoy trabajando con liftweb, maven y scala 2.9.

La excepción se envuelve con RuntimeException. Para atraparlo, tomo RuntimeException y examino su causa. En caso de que sea una violación de restricción, hago mi trabajo, de lo contrario rechazo la excepción. Véase el siguiente código:

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

Si la compilación falla con el siguiente error:

error: object mysql is not a member of package com 

verificación de la definición del paquete mysql en POM Maven. En mi caso, se definió como ámbito de tiempo de ejecución. Cambiarlo para compilar el alcance permitió que la compilación tuviera éxito y, en tiempo de ejecución, esta captura funciona correctamente. Aquí está la sección dependencia MySQL en pom.xml experto:

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