2012-11-05 9 views
11

Sto utilizzando la modalità di sospensione per l'inserimento in una tabella mysql in cui tutte le colonne sono definite come non null. Ha una chiave primaria univoca e un altro indice univoco su più colonne.org.springframework.dao.DataIntegrityViolationException causa errata di segnalazione?

sto ottenendo il seguente errore:

org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into MY_TABLE(col1, col2, col3, col4, ID_) values (?, ?, ?, ?, ?)]; constraint [null]

Questo errore è nei registri dei clienti e non riesco a riprodurre il problema me, quindi non posso mettere in debug per vedere quali sono i valori in la dichiarazione di inserimento.

La mia comprensione è che "vincolo [null]" significa che un vincolo "non nullo" è stato violato. Tuttavia, guardando il mio codice, non riesco a vedere alcun modo possibile per cui qualsiasi dato potrebbe essere nullo al momento dell'inserimento, a meno che Hibernate stia tentando di inserire un ID Null (che sarebbe un bug molto brutto in ibernazione e quindi sembra improbabile).

Tuttavia, posso vedere come potrebbe accadere che venga violato un vincolo univoco. È possibile che il messaggio sia fuorviante e in effetti sto ricevendo una violazione della chiave univoca? "Constraint [null]" indica sempre che un vincolo non nullo è stato violato?

+0

non riesco a immaginare il motivo per cui tale eccezione è causata a meno che un 'colonna non null' si cerca di dare un valore' null'. A proposito, se si sta utilizzando una versione precedente del driver JDBC, non dimenticare di sostituirlo con l'ultimo (10+). Altrimenti, causerà altri problemi anche in seguito. – Lion

+0

Questo è mysql 5.1, non Oracle. – Dana

risposta

11

Se si cerca il chiamante del costruttore del DataIntegrityViolationException nel codice sorgente di Primavera, ci si accorge che si chiama in org.springframework.orm.hibernate3.SessionFactoryUtils:

return new DataIntegrityViolationException(ex.getMessage() + "; SQL [" + jdbcEx.getSQL() + 
       "]; constraint [" + jdbcEx.getConstraintName() + "]", ex); 

Così l'eccezione è causata da un vincolo violato, e null è il nome del vincolo restituito dall'eccezione JDBC. Quindi dovresti dare la colpa al driver MySQL per non inserire il nome del vincolo violato nell'eccezione JDBC. Ma il vincolo violato potrebbe essere qualsiasi vincolo e non necessariamente un vincolo not null.

+1

Vedo, è molto fastidioso che mysql non stia dando il nome ma molto utile da sapere! Ho appena pensato che il null significasse un vincolo non nullo. Grazie. – Dana

1

è possibile ottenere il nome Constain direttamente dal tipo di eccezione di Hibernate. uso

getConstraintName

proprietà per ottenere DB vincolare nome.

} catch (ConstraintViolationException conEx) { 
      if (conEx.getConstraintName().contains("PROJECT_UK")) { 
       //TODO Project Entity is violating it's constrain 

Ho usato contiene perché voglio questa applicazione per l'esecuzione su più schemi di DB. Per impostazione predefinita getConstraintName viene fornito con il nome di DB come

MyDBName.ConstrainName

+0

Non esiste più un metodo getConstraintName() in ConstraintViolationException – Anna