HHH-11082 Log the failing SQL when the batched execution throws a RuntimeException (e.g. StaleStateException)
This commit is contained in:
parent
5527bd0d60
commit
f18656473d
|
@ -102,6 +102,7 @@ public class BatchingBatch extends AbstractBatchImpl {
|
||||||
LOG.debugf( "Executing batch size: %s", batchPosition );
|
LOG.debugf( "Executing batch size: %s", batchPosition );
|
||||||
try {
|
try {
|
||||||
for ( Map.Entry<String,PreparedStatement> entry : getStatements().entrySet() ) {
|
for ( Map.Entry<String,PreparedStatement> entry : getStatements().entrySet() ) {
|
||||||
|
String sql = entry.getKey();
|
||||||
try {
|
try {
|
||||||
final PreparedStatement statement = entry.getValue();
|
final PreparedStatement statement = entry.getValue();
|
||||||
final int[] rowCounts;
|
final int[] rowCounts;
|
||||||
|
@ -116,14 +117,16 @@ public class BatchingBatch extends AbstractBatchImpl {
|
||||||
}
|
}
|
||||||
catch ( SQLException e ) {
|
catch ( SQLException e ) {
|
||||||
abortBatch();
|
abortBatch();
|
||||||
throw sqlExceptionHelper().convert( e, "could not execute batch", entry.getKey() );
|
LOG.unableToExecuteBatch( e, sql );
|
||||||
}
|
throw sqlExceptionHelper().convert( e, "could not execute batch", sql );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch ( RuntimeException re ) {
|
catch ( RuntimeException re ) {
|
||||||
LOG.unableToExecuteBatch( re.getMessage() );
|
abortBatch();
|
||||||
|
LOG.unableToExecuteBatch( re, sql );
|
||||||
throw re;
|
throw re;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
batchPosition = 0;
|
batchPosition = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1066,8 +1066,8 @@ public interface CoreMessageLogger extends BasicLogger {
|
||||||
void unableToDropTemporaryIdTable(String message);
|
void unableToDropTemporaryIdTable(String message);
|
||||||
|
|
||||||
@LogMessage(level = ERROR)
|
@LogMessage(level = ERROR)
|
||||||
@Message(value = "Exception executing batch [%s]", id = 315)
|
@Message(value = "Exception executing batch [%s], SQL: %s", id = 315)
|
||||||
void unableToExecuteBatch(String message);
|
void unableToExecuteBatch(Exception e, String sql );
|
||||||
|
|
||||||
@LogMessage(level = WARN)
|
@LogMessage(level = WARN)
|
||||||
@Message(value = "Error executing resolver [%s] : %s", id = 316)
|
@Message(value = "Error executing resolver [%s] : %s", id = 316)
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.batch;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OptimisticLockException;
|
||||||
|
import javax.persistence.Version;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
|
||||||
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
public class BatchOptimisticLockingTest extends
|
||||||
|
BaseNonConfigCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[]{
|
||||||
|
Person.class,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addSettings(Map settings) {
|
||||||
|
settings.put( AvailableSettings.STATEMENT_BATCH_SIZE, String.valueOf( 2 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBatchAndOptimisticLocking() {
|
||||||
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
|
Person person1 = new Person();
|
||||||
|
person1.id = 1L;
|
||||||
|
person1.name = "First";
|
||||||
|
session.persist( person1 );
|
||||||
|
|
||||||
|
Person person2 = new Person();
|
||||||
|
person2.id = 2L;
|
||||||
|
person2.name = "Second";
|
||||||
|
session.persist( person2 );
|
||||||
|
|
||||||
|
Person person3 = new Person();
|
||||||
|
person3.id = 3L;
|
||||||
|
person3.name = "Third";
|
||||||
|
session.persist( person3 );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
try {
|
||||||
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
|
List<Person> persons = session.createQuery( "select p from Person p").getResultList();
|
||||||
|
|
||||||
|
for ( int i = 0; i < persons.size(); i++ ) {
|
||||||
|
Person person = persons.get( i );
|
||||||
|
person.name += " Person";
|
||||||
|
|
||||||
|
if ( i == 1 ) {
|
||||||
|
try {
|
||||||
|
executorService.submit( () -> {
|
||||||
|
doInHibernate( this::sessionFactory, _session -> {
|
||||||
|
Person _person = _session.find( Person.class, person.id );
|
||||||
|
_person.name += " Person is the new Boss!";
|
||||||
|
} );
|
||||||
|
} ).get();
|
||||||
|
}
|
||||||
|
catch (InterruptedException|ExecutionException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
catch (Exception expected) {
|
||||||
|
assertEquals( OptimisticLockException.class, expected.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Person")
|
||||||
|
public static class Person {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Version
|
||||||
|
private long version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue