2009-07-30 5 views
7

Sto lavorando a un'applicazione di database che è principalmente di sola lettura, ma esiste una tabella che registra il movimento dell'utente nell'app e contiene un numero elevato di scritture. Per ogni poche migliaia scrive, vediamo alcune eccezioni nel log degli errori in questo modo:Ottenere errori di immissione duplicati da Hibernate, è colpa di MySQL?

[WARN][2009-07-30 11:09:20,083][org.hibernate.util.JDBCExceptionReporter] SQL Error: 1062, SQLState: 23000 
[ERROR][2009-07-30 11:09:20,083][org.hibernate.util.JDBCExceptionReporter] Duplicate entry '17011' for key 1 
[ERROR][2009-07-30 11:09:20,083][org.hibernate.event.def.AbstractFlushingEventListener] Could not synchronize database state with session 
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) 

La tabella in questione ha il seguente schema:

CREATE TABLE IF NOT EXISTS `my_table` (
    `id` int(11) NOT NULL, 
    `data1` int(11) NOT NULL, 
    `data2` int(11) NOT NULL, 
    `timestamp` datetime default NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; 

e il corrispondente XML di mapping Hibernate:

È possibile, anche se improbabile, che più istanze della nostra webapp possano scrivere contemporaneamente nel database, poiché i numeri di versione nel nostro contesto webapp per rilasciare senza problemi nuova v ersioni delle applicazioni. I client con la vecchia versione dell'applicazione memorizzata nella cache nel loro browser Web accedono quindi alle vecchie versioni del server, che rimuoviamo dopo poche settimane.

Ad ogni modo, non sono convinto che questo sia il problema, ma sospetto che ci sia qualche problema di sincronizzazione tra MySQL e Hibernate. Cambiare il mio generatore in sequenza, seqhilo o hilo aiuto? Inoltre, se puoi fornire un esempio di configurazione di un generatore di questo tipo in MySQL, sarebbe molto utile, dato che la maggior parte delle risorse online sono semplicemente copiate dagli esempi dolorosamente minimalisti nel manuale di Hibernate.

risposta

9

L'incremento è decisamente negativo se si ha più di un processo di scrittura sulla stessa tabella: è necessario che si verifichi una collisione.

Dato che stiamo parlando di MySQL, la cosa più semplice da utilizzare sarebbe identity. Nel vostro mapping Hibernate:

<generator class="identity"/> 

Nello script MySQL:

CREATE TABLE IF NOT EXISTS `my_table` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `data1` int(11) NOT NULL, 
    `data2` int(11) NOT NULL, 
    `timestamp` datetime default NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; 

Per alterare una tabella esistente:

ALTER TABLE `my_table` 
    CHANGE COLUMN `id` `id` int(11) NOT NULL AUTO_INCREMENT=$NEW_VALUE$; 

dove $ NEW_VALUE $ dovrebbe essere sostituito dal successivo id disponibili in modo quella sequenza non viene ripristinata a 1.

+0

Risposta molto accurata e chiara - grazie! –