playframework - starter - play framework tutorial with scala
Cómo administrar Excepciones relacionadas con DB en Play! 2.0/Scala usando Anorm (2)
Estoy trabajando en un patio de recreo un poco diferente pero, hasta donde yo entiendo, resolví 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. Vea 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 construcción falla con el siguiente error:
error: object mysql is not a member of package com
verifique la definición del paquete mysql en maven pom. 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 de dependencia de mysql en maven pom.xml:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
<scope>runtime</scope>
</dependency>
Actualmente estoy jugando con Play 2.0 (Scala). Debo admitir que es muy divertido. Tengo una pregunta relacionada con las excepciones de operaciones de la base de datos .
Digamos que tengo Car como una clase de dominio y que tengo una restricción de integridad en uno de los campos, digamos el modelo, por lo que en el archivo db no puedo tener dos (2) filas con el 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 capturo la excepción como en el código anterior, cuando invoco este método desde mi controlador con un modelo que ya tiene un valor en la base de datos, me sale la siguiente excepción:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry ''Enzo'' for key ''model''
¿Hay alguna manera de detectar MySQLIntegrityConstraintViolationException en lugar de Exception para tener un control detallado de 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 DB o hay alguna de las mejores prácticas que todo el mundo usa?
gracias por adelantado,
Creo que te ves 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 lo sé, ya que también estoy jugando con este marco :).
En cuanto a la retroalimentación para el usuario ... tal vez el alcance de Flash es una buena forma de comunicar frases sueltas a la "página siguiente" (por ejemplo, si el automóvil se guardó correctamente o no). Consulte: http://www.playframework.org/documentation/2.0/ScalaSessionFlash (Desplácese hasta ''Alcance del flash'').