HHH-14763 Avoid suppress exceptions in try/finally
This commit is contained in:
parent
6314395edf
commit
f24b91da2a
|
@ -111,6 +111,7 @@ import org.hibernate.event.spi.SaveOrUpdateEventListener;
|
||||||
import org.hibernate.graph.GraphSemantic;
|
import org.hibernate.graph.GraphSemantic;
|
||||||
import org.hibernate.graph.internal.RootGraphImpl;
|
import org.hibernate.graph.internal.RootGraphImpl;
|
||||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||||
|
import org.hibernate.internal.util.ExceptionHelper;
|
||||||
import org.hibernate.jpa.AvailableSettings;
|
import org.hibernate.jpa.AvailableSettings;
|
||||||
import org.hibernate.jpa.QueryHints;
|
import org.hibernate.jpa.QueryHints;
|
||||||
import org.hibernate.jpa.internal.util.CacheModeHelper;
|
import org.hibernate.jpa.internal.util.CacheModeHelper;
|
||||||
|
@ -712,6 +713,7 @@ public class SessionImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
private void firePersist(final PersistEvent event) {
|
private void firePersist(final PersistEvent event) {
|
||||||
|
Throwable originalException = null;
|
||||||
try {
|
try {
|
||||||
checkTransactionSynchStatus();
|
checkTransactionSynchStatus();
|
||||||
checkNoUnresolvedActionsBeforeOperation();
|
checkNoUnresolvedActionsBeforeOperation();
|
||||||
|
@ -719,18 +721,36 @@ public class SessionImpl
|
||||||
fastSessionServices.eventListenerGroup_PERSIST.fireEventOnEachListener( event, PersistEventListener::onPersist );
|
fastSessionServices.eventListenerGroup_PERSIST.fireEventOnEachListener( event, PersistEventListener::onPersist );
|
||||||
}
|
}
|
||||||
catch (MappingException e) {
|
catch (MappingException e) {
|
||||||
throw getExceptionConverter().convert( new IllegalArgumentException( e.getMessage() ) );
|
originalException = getExceptionConverter().convert( new IllegalArgumentException( e.getMessage() ) );
|
||||||
}
|
}
|
||||||
catch (RuntimeException e) {
|
catch (RuntimeException e) {
|
||||||
throw getExceptionConverter().convert( e );
|
originalException = getExceptionConverter().convert( e );
|
||||||
|
}
|
||||||
|
catch (Throwable t1) {
|
||||||
|
originalException = t1;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
Throwable suppressed = null;
|
||||||
try {
|
try {
|
||||||
checkNoUnresolvedActionsAfterOperation();
|
checkNoUnresolvedActionsAfterOperation();
|
||||||
}
|
}
|
||||||
catch (RuntimeException e) {
|
catch (RuntimeException e) {
|
||||||
throw getExceptionConverter().convert( e );
|
suppressed = getExceptionConverter().convert( e );
|
||||||
}
|
}
|
||||||
|
catch (Throwable t2) {
|
||||||
|
suppressed = t2;
|
||||||
|
}
|
||||||
|
if ( suppressed != null ) {
|
||||||
|
if ( originalException == null ) {
|
||||||
|
originalException = suppressed;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
originalException.addSuppressed( suppressed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( originalException != null ) {
|
||||||
|
ExceptionHelper.doThrow( originalException );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.internal.util;
|
||||||
|
|
||||||
|
|
||||||
|
public final class ExceptionHelper {
|
||||||
|
|
||||||
|
private ExceptionHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws the given throwable even if it is a checked exception.
|
||||||
|
*
|
||||||
|
* @param e The throwable to throw.
|
||||||
|
*/
|
||||||
|
public static void doThrow(Throwable e) {
|
||||||
|
ExceptionHelper.<RuntimeException>doThrow0(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T extends Throwable> void doThrow0(Throwable e) throws T {
|
||||||
|
throw (T) e;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.hibernate.internal.log.ConnectionAccessLogger;
|
import org.hibernate.internal.log.ConnectionAccessLogger;
|
||||||
|
import org.hibernate.internal.util.ExceptionHelper;
|
||||||
import org.hibernate.resource.transaction.spi.DdlTransactionIsolator;
|
import org.hibernate.resource.transaction.spi.DdlTransactionIsolator;
|
||||||
import org.hibernate.tool.schema.internal.exec.JdbcContext;
|
import org.hibernate.tool.schema.internal.exec.JdbcContext;
|
||||||
|
|
||||||
|
@ -81,29 +82,46 @@ public class DdlTransactionIsolatorNonJtaImpl implements DdlTransactionIsolator
|
||||||
@Override
|
@Override
|
||||||
public void release() {
|
public void release() {
|
||||||
if ( jdbcConnection != null ) {
|
if ( jdbcConnection != null ) {
|
||||||
|
Throwable originalException = null;
|
||||||
try {
|
try {
|
||||||
if ( unsetAutoCommit ) {
|
if ( unsetAutoCommit ) {
|
||||||
try {
|
try {
|
||||||
jdbcConnection.setAutoCommit( false );
|
jdbcConnection.setAutoCommit( false );
|
||||||
}
|
}
|
||||||
catch (SQLException e) {
|
catch (SQLException e) {
|
||||||
throw jdbcContext.getSqlExceptionHelper().convert(
|
originalException = jdbcContext.getSqlExceptionHelper().convert(
|
||||||
e,
|
e,
|
||||||
"Unable to set auto commit to false for JDBC Connection used for DDL execution"
|
"Unable to set auto commit to false for JDBC Connection used for DDL execution" );
|
||||||
);
|
}
|
||||||
|
catch (Throwable t1) {
|
||||||
|
originalException = t1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
Throwable suppressed = null;
|
||||||
try {
|
try {
|
||||||
jdbcContext.getJdbcConnectionAccess().releaseConnection( jdbcConnection );
|
jdbcContext.getJdbcConnectionAccess().releaseConnection( jdbcConnection );
|
||||||
}
|
}
|
||||||
catch (SQLException e) {
|
catch (SQLException e) {
|
||||||
throw jdbcContext.getSqlExceptionHelper().convert(
|
suppressed = jdbcContext.getSqlExceptionHelper().convert(
|
||||||
e,
|
e,
|
||||||
"Unable to release JDBC Connection used for DDL execution"
|
"Unable to release JDBC Connection used for DDL execution" );
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
catch (Throwable t2) {
|
||||||
|
suppressed = t2;
|
||||||
|
}
|
||||||
|
if ( suppressed != null ) {
|
||||||
|
if ( originalException == null ) {
|
||||||
|
originalException = suppressed;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
originalException.addSuppressed( suppressed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( originalException != null ) {
|
||||||
|
ExceptionHelper.doThrow( originalException );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||||
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
import org.hibernate.engine.transaction.spi.IsolationDelegate;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
import org.hibernate.internal.util.ExceptionHelper;
|
||||||
import org.hibernate.jdbc.WorkExecutor;
|
import org.hibernate.jdbc.WorkExecutor;
|
||||||
import org.hibernate.jdbc.WorkExecutorVisitable;
|
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
|
|
||||||
|
@ -103,36 +104,40 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T doInSuspendedTransaction(HibernateCallable<T> callable) {
|
private <T> T doInSuspendedTransaction(HibernateCallable<T> callable) {
|
||||||
|
Throwable originalException = null;
|
||||||
try {
|
try {
|
||||||
// First we suspend any current JTA transaction
|
// First we suspend any current JTA transaction
|
||||||
Transaction surroundingTransaction = transactionManager.suspend();
|
Transaction surroundingTransaction = transactionManager.suspend();
|
||||||
LOG.debugf( "Surrounding JTA transaction suspended [%s]", surroundingTransaction );
|
LOG.debugf( "Surrounding JTA transaction suspended [%s]", surroundingTransaction );
|
||||||
|
|
||||||
boolean hadProblems = false;
|
|
||||||
try {
|
try {
|
||||||
return callable.call();
|
return callable.call();
|
||||||
}
|
}
|
||||||
catch (HibernateException e) {
|
catch (Throwable t1) {
|
||||||
hadProblems = true;
|
originalException = t1;
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
transactionManager.resume( surroundingTransaction );
|
transactionManager.resume( surroundingTransaction );
|
||||||
LOG.debugf( "Surrounding JTA transaction resumed [%s]", surroundingTransaction );
|
LOG.debugf( "Surrounding JTA transaction resumed [%s]", surroundingTransaction );
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable t2) {
|
||||||
// if the actually work had an error use that, otherwise error based on t
|
// if the actually work had an error use that, otherwise error based on t
|
||||||
if ( !hadProblems ) {
|
if ( originalException == null ) {
|
||||||
//noinspection ThrowFromFinallyBlock
|
originalException = new HibernateException( "Unable to resume previously suspended transaction", t2 );
|
||||||
throw new HibernateException( "Unable to resume previously suspended transaction", t );
|
}
|
||||||
|
else {
|
||||||
|
originalException.addSuppressed( t2 ); // No extra nesting, directly t2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SystemException e) {
|
catch (SystemException e) {
|
||||||
throw new HibernateException( "Unable to suspend current JTA transaction", e );
|
originalException = new HibernateException( "Unable to suspend current JTA transaction", e );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExceptionHelper.doThrow( originalException );
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T doInNewTransaction(HibernateCallable<T> callable, TransactionManager transactionManager) {
|
private <T> T doInNewTransaction(HibernateCallable<T> callable, TransactionManager transactionManager) {
|
||||||
|
|
Loading…
Reference in New Issue