2010-05-23 12 views
11

Considere la siguiente clase de entidad, que se utiliza con, por ejemplo, EclipseLink 2.0.2, donde el atributo link no es la clave principal, sino único.Infracciones de restricción de captura en JPA 2.0

@Entity 
public class Profile { 
    @Id 
    private Long id; 

    @Column(unique = true) 
    private String link; 

    // Some more attributes and getter and setter methods 
} 

Al insertar registros con un valor duplicado para el atributo link, EclipseLink no significa lanzar una EntityExistsException, pero lanza un DatabaseException, con el mensaje que explica que la restricción única se violó.

Esto no parece muy útil, ya que no habría una manera simple, independiente de la base de datos, de detectar esta excepción. ¿Cuál sería la forma recomendada de lidiar con esto?

Un par de cosas que he consideradas son:

  • Comprobación del código de error en el DatabaseException - Me temo que este código de error, sin embargo, es el código de error nativo para la base de datos;
  • Comprobando la existencia de un Profile con el valor específico para link de antemano, esto obviamente resultaría en una enorme cantidad de consultas superfluas.
+0

He enviado un error para este problema. Vota por ello para que podamos solucionar este problema: https://bugs.eclipse.org/bugs/show_bug.cgi?id=375745 – sdoca

Respuesta

5

Al insertar registros con un valor duplicado para el atributo de enlace, EclipseLink no lanzar una EntityExistsException

Sí, y no se supone que un proveedor JPA a lanzar una EntityExistException en ese caso, no obtendrá un EntityExistException en otra cosa que no sea la clave principal.

(...) pero arroja una excepción DatabaseException, con el mensaje que explica que la restricción única fue violada.

Esto es muy MAL de EclipseLink, un proveedor JPA debe lanzar un o una subclase PersistenceException pero ciertamente no es una excepción específica como o.e.p.e.DatabaseException. Este es un error y se debe informar como tal, como ya mencioné en un previous answer.

Esto no parece muy útil, ya que no habría una manera simple, independiente de la base de datos, de detectar esta excepción. ¿Cuál sería la forma recomendada de lidiar con esto?

La misma respuesta que la anterior, vea mi previous answer.

+0

Dado que mencionas EclipseLink en particular aquí: ¿Conoces otros proveedores de JPA que se comporten correctamente? ? – Hank

+0

@Hank Tal vez el problema está solucionado en versiones recientes, no se puede decir. Pero que yo sepa, Hibernate arroja una 'PersistenceException' en tal caso. –

2

Es una lástima que no tengan una excepción de restricción de constricción en JPA. Creé un método de ayuda para determinar si la PersistenceException es una violación de restricción para una clase determinada, aunque solo está hibernado. Me imagino que hay una manera de hacerlo utilizando otras implementaciones.

protected Boolean isUniqueConstraintViolation(PersistenceException ex, Class entity) { 

    if (((NonUniqueObjectException)ex.getCause()).getEntityName().equals(entity.getName())) { 
     return true; 
    } 

    return false; 
} 
Cuestiones relacionadas