HHH-10510 - Root cause not properly extracted when transaction commit fails
This commit is contained in:
parent
2dc6bd591b
commit
fd6aadcd2a
|
@ -63,11 +63,12 @@ public class TransactionImpl implements EntityTransaction {
|
|||
catch (Exception e) {
|
||||
Throwable wrappedException;
|
||||
if ( e instanceof PersistenceException ) {
|
||||
if ( e.getCause() instanceof HibernateException ) {
|
||||
wrappedException = entityManager.convert( (HibernateException) e.getCause() );
|
||||
Throwable cause = e.getCause() == null ? e : e.getCause();
|
||||
if ( cause instanceof HibernateException ) {
|
||||
wrappedException = entityManager.convert( (HibernateException) cause );
|
||||
}
|
||||
else {
|
||||
wrappedException = e.getCause();
|
||||
wrappedException = cause;
|
||||
}
|
||||
}
|
||||
else if ( e instanceof HibernateException ) {
|
||||
|
|
|
@ -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.jpa.test.transaction;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||
import org.hibernate.jpa.boot.spi.Bootstrap;
|
||||
import org.hibernate.jpa.test.PersistenceUnitDescriptorAdapter;
|
||||
import org.hibernate.jpa.test.SettingsGenerator;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class TransactionCommitFailureTest {
|
||||
|
||||
public static final String COMMIT_FAILURE = "Commit failed!";
|
||||
|
||||
private static final AtomicBoolean transactionFailureTrigger = new AtomicBoolean( false );
|
||||
|
||||
@Test
|
||||
public void testConfiguredInterceptor() {
|
||||
Map settings = basicSettings();
|
||||
EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder( new PersistenceUnitDescriptorAdapter(), settings ).build();
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
try {
|
||||
em.getTransaction().begin();
|
||||
transactionFailureTrigger.set( true );
|
||||
em.getTransaction().commit();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
assertEquals(PersistenceException.class, e.getCause().getClass());
|
||||
assertEquals(COMMIT_FAILURE, e.getCause().getMessage());
|
||||
}
|
||||
finally {
|
||||
if ( em.getTransaction() != null && em.getTransaction().isActive() ) {
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
em.close();
|
||||
emf.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected Map basicSettings() {
|
||||
return SettingsGenerator.generateSettings(
|
||||
Environment.HBM2DDL_AUTO, "create-drop",
|
||||
Environment.USE_NEW_ID_GENERATOR_MAPPINGS, "true",
|
||||
Environment.DIALECT, Dialect.getDialect().getClass().getName(),
|
||||
Environment.CONNECTION_PROVIDER, ProxyConnectionProvider.class.getName()
|
||||
);
|
||||
}
|
||||
|
||||
public static class ProxyConnectionProvider extends DriverManagerConnectionProviderImpl {
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
Connection delegate = super.getConnection();
|
||||
return (Connection) Proxy.newProxyInstance(
|
||||
this.getClass().getClassLoader(),
|
||||
new Class[]{Connection.class},
|
||||
new ConnectionInvocationHandler(delegate));
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConnectionInvocationHandler implements InvocationHandler {
|
||||
|
||||
private final Connection delegate;
|
||||
|
||||
public ConnectionInvocationHandler(Connection delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if("commit".equals( method.getName() )) {
|
||||
if ( transactionFailureTrigger.get() ) {
|
||||
throw new PersistenceException( COMMIT_FAILURE );
|
||||
}
|
||||
}
|
||||
else if("rollback".equals( method.getName() )) {
|
||||
if ( transactionFailureTrigger.get() ) {
|
||||
transactionFailureTrigger.set( false );
|
||||
throw new PersistenceException( "Rollback failed!" );
|
||||
}
|
||||
}
|
||||
return method.invoke(delegate, args);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue