Il mio progetto utilizza la modalità di sospensione con il gestore delle transazioni primavera e il mio database è postgres (potrebbe non essere rilevante).vincolo database di gestione ibernazione
Sto cercando di leggere grandi file xml e di costruire oggetti da questi (gli oggetti non sono grandi ma la quantità è) e li inseriamo nel database.
Se per caso uno dei miei oggetti viola il vincolo del database, l'intero processo si interrompe. Come posso saltare quelli che violano il vincolo del database? in alternativa registra il loro id o qualunque cosa su un file di log?
aggiornamento Domanda:
Sto passando in rassegna attraverso SO e ha scoperto che per gli inserti in batch è meglio consiglia di utilizzare sessione Stateless, ma ho ancora lo stesso problema e inserto ferma:
May 26, 2012 4:45:47 PM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: ERROR: duplicate key value violates unique constraint "UN_FK"
Detail: Key (fid)=(H1) already exists.
Ecco le parti rilevanti del mio codice per l'analisi di xml e l'inserimento in db, per semplicità assumiamo che sto inserendo filmati:
//class field
@Autowired
private SessionFactory sessionFactory;
@Override
public void startDocument() throws SAXException {
session = sessionFactory.getCurrentSession();
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("FILM")) {
movie.setCategory(category);
movie.setAdded(new Date());
session.insert(movie);
}
}
I e ho impostato questa proprietà nell'app-ctx hibernate.jdbc.batch_size
su 100. È davvero necessario selezionare prima di inserire per evitare questo?
Aggiornamento 2:
Se uso StatelessSession
invece della sessione, ottengo arround 20 inserti e che le fermate di trasformazione a tempo indeterminato senza alcuna eccezione o nulla.
Suppongo che il numero 20 sia perché sto collegando le connessioni con tomcat e ho maxActive="20"
.
Bounty Aggiornamento:
Mi piacerebbe davvero vedere qualcuno soluzione offerta (senza selezionare difensiva se possibile). Utilizzo di statelessSession o solo sessione.
Una semplice istruzione try cattura non lo farà. Una volta che un'eccezione viene generata da Hibernate, lo stato della sessione è incoerente, la transazione deve essere ripristinata e la sessione chiusa. Inoltre, l'eccezione verrà lanciata solo al momento del flush, molto tempo dopo che il record difettoso è stato mantenuto. –
Ecco perché è consigliabile utilizzare una sessione di sospensione stateless per tali casi. Eviterà lo stato incoerente e ridurrà anche il consumo di memoria (o non dovrai rimuovere le entità già trattate) –