2010-05-23 12 views
11

Si consideri la seguente classe di entità, utilizzata con, ad esempio, EclipseLink 2.0.2 - in cui l'attributo link non è la chiave primaria, ma è tuttavia univoco.Violazioni dei vincoli di cattura in 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 
} 

Quando inserisco i record con un valore duplicato per l'attributo link, EclipseLink non significa gettare un EntityExistsException, ma getta un DatabaseException, con il messaggio che spiega che il vincolo unico è stato violato.

Questo non sembra molto utile, in quanto non ci sarebbe un modo semplice, indipendente dal database, per cogliere questa eccezione. Quale sarebbe il modo consigliato per affrontare questo?

Un paio di cose che ho considerati sono:

  • Verifica del codice di errore sul DatabaseException - temo che questo codice di errore, però, è il codice di errore nativo per il database;
  • Controllare l'esistenza di un Profile con il valore specifico per link in anticipo - questo ovviamente comporterebbe un'enorme quantità di query superflue.
+0

Ho inviato un bug per questo problema. Si prega di votare per risolvere il problema: https://bugs.eclipse.org/bugs/show_bug.cgi?id=375745 – sdoca

risposta

5

Quando inserisco i record con un valore duplicato per l'attributo di collegamento, EclipseLink non gettare un EntityExistsException

Sì, e un provider JPA non dovrebbe gettare un EntityExistException in quel caso, non avrai un EntityExistException su qualcosa di diverso dalla chiave primaria.

(...) ma genera un DatabaseException, con il messaggio che spiega che il vincolo univoco è stato violato.

Questo è molto SBAGLIATO da EclipseLink, un provider JPA dovrebbe gettare un PersistenceException o di una sottoclasse, ma non certo un'eccezione specifica come o.e.p.e.DatabaseException. Questo è un bug e dovrebbe essere segnalato come tale ho già menzionato in un previous answer.

Questo non sembra molto utile, in quanto non ci sarebbe un modo semplice, indipendente dal database, di cogliere questa eccezione. Quale sarebbe il modo consigliato per affrontare questo?

Stessa risposta di cui sopra, vedere il mio previous answer.

+0

Dato che si parla di EclipseLink in particolare qui: conosci altri fornitori JPA che si comportano correttamente ? – Hank

+0

@Hank Forse il problema è stato risolto nelle versioni recenti, non posso dire. Ma per quanto ne so, Hibernate lancia una "PersistenceException" in tal caso. –

2

È un peccato che non abbiano una ConstraintViolationException in JPA. Ho creato un metodo di supporto per determinare se PersistenceException è una violazione del vincolo per una determinata classe, ma è solo in ibernazione. Immagino ci sia un modo per farlo usando altre implementazioni.

protected Boolean isUniqueConstraintViolation(PersistenceException ex, Class entity) { 

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

    return false; 
} 
Problemi correlati