问题
I'm updating a very large number of objects in batches and want to ignore any duplicates. What is the best way of doing this?
My understanding is that if a ConstrainViolationException is thrown all the other objects in the batch will NOT be persisted.
回答1:
This was my solution:
private void saveBatch() {
StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
try {
for (Object t : batchList) {
session.insert(t);
}
tx.commit();
} catch (ConstraintViolationException e) {
log.info("Duplicate in batch...save individually");
tx.rollback();
session.close();
saveIndividually();
return;
}
session.close();
batchList.clear();
}
private void saveIndividually() {
StatelessSession session = sessionFactory.openStatelessSession();
for (Object t : batchList) {
Transaction tx = session.beginTransaction();
session.insert(t);
try {
tx.commit();
} catch (ConstraintViolationException e) {
tx.rollback();
log.warn("Ignoring duplicate: " + t);
}
}
session.close();
batchList.clear();
}
回答2:
Well one way to insure consistency is to make sure all your entities' associations have the proper cascade options configured (like, if you want that a certain entity, when persisted, will also persist any new associated entities contained within its associations, you should configure cascade="save-update").
If you don't/ can't do that, the theoretical alternative is to create a separate transaction for each of your batch's operations (like each entity insertion), and if that transaction rolls back due to exception, you catch the exception and continue (possibly keeping a cache of the failed transactions to retry them later). This however will most likely not be practical, as it will take a whole lot longer to process than if you do all your operations inside one transaction (a true batch update).
Personally, when I'm confronted with such a scenario I do the batch operations via JDBC (using the Hibernate schema, and making sure to have the same sequences generation). This way it's faster and you can't more accuratelly deal with such issues.
来源:https://stackoverflow.com/questions/8138559/hibernate-batch-updates-with-constraintviolationexception