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.internal.RootGraphImpl;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.internal.util.ExceptionHelper;
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.QueryHints;
|
||||
import org.hibernate.jpa.internal.util.CacheModeHelper;
|
||||
|
@ -712,6 +713,7 @@ public class SessionImpl
|
|||
}
|
||||
|
||||
private void firePersist(final PersistEvent event) {
|
||||
Throwable originalException = null;
|
||||
try {
|
||||
checkTransactionSynchStatus();
|
||||
checkNoUnresolvedActionsBeforeOperation();
|
||||
|
@ -719,18 +721,36 @@ public class SessionImpl
|
|||
fastSessionServices.eventListenerGroup_PERSIST.fireEventOnEachListener( event, PersistEventListener::onPersist );
|
||||
}
|
||||
catch (MappingException e) {
|
||||
throw getExceptionConverter().convert( new IllegalArgumentException( e.getMessage() ) );
|
||||
originalException = getExceptionConverter().convert( new IllegalArgumentException( e.getMessage() ) );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
throw getExceptionConverter().convert( e );
|
||||
originalException = getExceptionConverter().convert( e );
|
||||
}
|
||||
catch (Throwable t1) {
|
||||
originalException = t1;
|
||||
}
|
||||
finally {
|
||||
Throwable suppressed = null;
|
||||
try {
|
||||
checkNoUnresolvedActionsAfterOperation();
|
||||
}
|
||||
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 org.hibernate.internal.log.ConnectionAccessLogger;
|
||||
import org.hibernate.internal.util.ExceptionHelper;
|
||||
import org.hibernate.resource.transaction.spi.DdlTransactionIsolator;
|
||||
import org.hibernate.tool.schema.internal.exec.JdbcContext;
|
||||
|
||||
|
@ -81,29 +82,46 @@ public class DdlTransactionIsolatorNonJtaImpl implements DdlTransactionIsolator
|
|||
@Override
|
||||
public void release() {
|
||||
if ( jdbcConnection != null ) {
|
||||
Throwable originalException = null;
|
||||
try {
|
||||
if ( unsetAutoCommit ) {
|
||||
try {
|
||||
jdbcConnection.setAutoCommit( false );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcContext.getSqlExceptionHelper().convert(
|
||||
originalException = jdbcContext.getSqlExceptionHelper().convert(
|
||||
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 {
|
||||
Throwable suppressed = null;
|
||||
try {
|
||||
jdbcContext.getJdbcConnectionAccess().releaseConnection( jdbcConnection );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcContext.getSqlExceptionHelper().convert(
|
||||
suppressed = jdbcContext.getSqlExceptionHelper().convert(
|
||||
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.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ExceptionHelper;
|
||||
import org.hibernate.jdbc.WorkExecutor;
|
||||
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||
|
||||
|
@ -103,36 +104,40 @@ public class JtaIsolationDelegate implements IsolationDelegate {
|
|||
}
|
||||
|
||||
private <T> T doInSuspendedTransaction(HibernateCallable<T> callable) {
|
||||
Throwable originalException = null;
|
||||
try {
|
||||
// First we suspend any current JTA transaction
|
||||
Transaction surroundingTransaction = transactionManager.suspend();
|
||||
LOG.debugf( "Surrounding JTA transaction suspended [%s]", surroundingTransaction );
|
||||
|
||||
boolean hadProblems = false;
|
||||
try {
|
||||
return callable.call();
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
hadProblems = true;
|
||||
throw e;
|
||||
catch (Throwable t1) {
|
||||
originalException = t1;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
transactionManager.resume( 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 ( !hadProblems ) {
|
||||
//noinspection ThrowFromFinallyBlock
|
||||
throw new HibernateException( "Unable to resume previously suspended transaction", t );
|
||||
if ( originalException == null ) {
|
||||
originalException = new HibernateException( "Unable to resume previously suspended transaction", t2 );
|
||||
}
|
||||
else {
|
||||
originalException.addSuppressed( t2 ); // No extra nesting, directly t2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue