Fix JPA Transaction#commit() does not throw RollbacackException

This commit is contained in:
Andrea Boriero 2016-05-02 11:09:56 +01:00 committed by Steve Ebersole
parent 3637bd342d
commit 4f1bca75bc
12 changed files with 435 additions and 639 deletions

View File

@ -0,0 +1,56 @@
/*
* 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.engine.spi;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.JDBCException;
import org.hibernate.LockOptions;
/**
* @author Andrea Boriero
*/
public interface ExceptionConverter {
/**
* Converts the exception thrown during the transaction commit phase
*
* @param e The exception being handled
*
* @return The converted exception
*/
RuntimeException convertCommitException(RuntimeException e);
/**
* Converts a Hibernate-specific exception into a JPA-specified exception; note that the JPA sepcification makes use
* of exceptions outside its exception hierarchy, though they are all runtime exceptions.
* <p/>
*
* @param e The Hibernate excepton.
* @param lockOptions The lock options in effect at the time of exception (can be null)
*
* @return The JPA-specified exception
*/
RuntimeException convert(HibernateException e, LockOptions lockOptions);
/**
* Converts a Hibernate-specific exception into a JPA-specified exception; note that the JPA sepcification makes use
* of exceptions outside its exception hierarchy, though they are all runtime exceptions.
* <p/>
*
* @param e The Hibernate excepton.
*
* @return The JPA-specified exception
*/
RuntimeException convert(HibernateException e);
RuntimeException convert(RuntimeException e);
RuntimeException convert(RuntimeException e, LockOptions lockOptions);
JDBCException convert(SQLException e, String message);
}

View File

@ -17,7 +17,6 @@ import javax.persistence.EntityGraph;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.FlushModeType; import javax.persistence.FlushModeType;
import javax.persistence.LockModeType; import javax.persistence.LockModeType;
import javax.persistence.PersistenceException;
import javax.persistence.StoredProcedureQuery; import javax.persistence.StoredProcedureQuery;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete; import javax.persistence.criteria.CriteriaDelete;
@ -145,41 +144,6 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
return delegate.isTransactionInProgress(); return delegate.isTransactionInProgress();
} }
@Override
public void handlePersistenceException(PersistenceException e) {
delegate.handlePersistenceException( e );
}
@Override
public void throwPersistenceException(PersistenceException e) {
delegate.throwPersistenceException( e );
}
@Override
public RuntimeException convert(HibernateException e, LockOptions lockOptions) {
return delegate.convert( e, lockOptions );
}
@Override
public RuntimeException convert(RuntimeException e) {
return delegate.convert( e );
}
@Override
public RuntimeException convert(HibernateException e) {
return delegate.convert( e );
}
@Override
public void throwPersistenceException(HibernateException e) {
delegate.throwPersistenceException( e );
}
@Override
public PersistenceException wrapStaleStateException(StaleStateException e) {
return delegate.wrapStaleStateException( e );
}
@Override @Override
public LockOptions getLockRequest(LockModeType lockModeType, Map<String, Object> properties) { public LockOptions getLockRequest(LockModeType lockModeType, Map<String, Object> properties) {
return delegate.getLockRequest( lockModeType, properties ); return delegate.getLockRequest( lockModeType, properties );
@ -459,6 +423,11 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
return delegate.getLoadQueryInfluencers(); return delegate.getLoadQueryInfluencers();
} }
@Override
public ExceptionConverter getExceptionConverter() {
return delegate.getExceptionConverter();
}
@Override @Override
public SessionEventListenerManager getEventListenerManager() { public SessionEventListenerManager getEventListenerManager() {
return delegate.getEventListenerManager(); return delegate.getEventListenerManager();

View File

@ -12,18 +12,15 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import javax.persistence.FlushModeType; import javax.persistence.FlushModeType;
import javax.persistence.PersistenceException;
import org.hibernate.CacheMode; import org.hibernate.CacheMode;
import org.hibernate.Criteria; import org.hibernate.Criteria;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Interceptor; import org.hibernate.Interceptor;
import org.hibernate.LockOptions;
import org.hibernate.ScrollMode; import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults; import org.hibernate.ScrollableResults;
import org.hibernate.SharedSessionContract; import org.hibernate.SharedSessionContract;
import org.hibernate.StaleStateException;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.jdbc.LobCreationContext; import org.hibernate.engine.jdbc.LobCreationContext;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
@ -142,57 +139,6 @@ public interface SharedSessionContractImplementor
*/ */
void markForRollbackOnly(); void markForRollbackOnly();
/**
* Handles marking for rollback and other such operations that need to occur depending on the type of
* exception being handled.
*
* @param e The exception being handled.
*/
void handlePersistenceException(PersistenceException e);
/**
* Delegates to {@link #handlePersistenceException} and then throws the given exception.
*
* @param e The exception being handled and finally thrown.
*/
void throwPersistenceException(PersistenceException e);
/**
* Converts a Hibernate-specific exception into a JPA-specified exception; note that the JPA sepcification makes use
* of exceptions outside its exception hierarchy, though they are all runtime exceptions.
* <p/>
* Any appropriate/needed calls to {@link #handlePersistenceException} are also made.
*
* @param e The Hibernate excepton.
* @param lockOptions The lock options in effect at the time of exception (can be null)
*
* @return The JPA-specified exception
*/
RuntimeException convert(HibernateException e, LockOptions lockOptions);
/**
* Converts a Hibernate-specific exception into a JPA-specified exception; note that the JPA sepcification makes use
* of exceptions outside its exception hierarchy, though they are all runtime exceptions.
* <p/>
* Any appropriate/needed calls to {@link #handlePersistenceException} are also made.
*
* @param e The Hibernate excepton.
*
* @return The JPA-specified exception
*/
RuntimeException convert(HibernateException e);
RuntimeException convert(RuntimeException e);
/**
* Delegates to {@link #convert} and then throws the given exception.
*
* @param e The exception being handled and finally thrown.
*/
void throwPersistenceException(HibernateException e);
PersistenceException wrapStaleStateException(StaleStateException e);
/** /**
* System time beforeQuery the start of the transaction * System time beforeQuery the start of the transaction
*/ */
@ -451,4 +397,6 @@ public interface SharedSessionContractImplementor
* should never be null. * should never be null.
*/ */
LoadQueryInfluencers getLoadQueryInfluencers(); LoadQueryInfluencers getLoadQueryInfluencers();
ExceptionConverter getExceptionConverter();
} }

View File

@ -10,6 +10,7 @@ import javax.transaction.Synchronization;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.TransactionException; import org.hibernate.TransactionException;
import org.hibernate.engine.spi.ExceptionConverter;
import org.hibernate.engine.transaction.spi.TransactionImplementor; import org.hibernate.engine.transaction.spi.TransactionImplementor;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.resource.transaction.spi.TransactionCoordinator; import org.hibernate.resource.transaction.spi.TransactionCoordinator;
@ -27,10 +28,12 @@ public class TransactionImpl implements TransactionImplementor {
private static final Logger LOG = CoreLogging.logger( TransactionImpl.class ); private static final Logger LOG = CoreLogging.logger( TransactionImpl.class );
private final TransactionCoordinator transactionCoordinator; private final TransactionCoordinator transactionCoordinator;
private final ExceptionConverter exceptionConverter;
private TransactionDriver transactionDriverControl; private TransactionDriver transactionDriverControl;
public TransactionImpl(TransactionCoordinator transactionCoordinator) { public TransactionImpl(TransactionCoordinator transactionCoordinator, ExceptionConverter exceptionConverter) {
this.transactionCoordinator = transactionCoordinator; this.transactionCoordinator = transactionCoordinator;
this.exceptionConverter = exceptionConverter;
} }
@Override @Override
@ -60,8 +63,12 @@ public class TransactionImpl implements TransactionImplementor {
} }
LOG.debug( "committing" ); LOG.debug( "committing" );
try {
internalGetTransactionDriverControl().commit(); internalGetTransactionDriverControl().commit();
}
catch (RuntimeException e) {
throw exceptionConverter.convertCommitException( e );
}
} }
public TransactionDriver internalGetTransactionDriverControl() { public TransactionDriver internalGetTransactionDriverControl() {

View File

@ -13,16 +13,7 @@ import java.io.Serializable;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityNotFoundException;
import javax.persistence.FlushModeType; import javax.persistence.FlushModeType;
import javax.persistence.LockTimeoutException;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.persistence.PessimisticLockException;
import javax.persistence.QueryTimeoutException;
import javax.persistence.Tuple; import javax.persistence.Tuple;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
@ -33,27 +24,15 @@ import org.hibernate.FlushMode;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.Interceptor; import org.hibernate.Interceptor;
import org.hibernate.JDBCException;
import org.hibernate.LockMode; import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.MultiTenancyStrategy; import org.hibernate.MultiTenancyStrategy;
import org.hibernate.ObjectNotFoundException;
import org.hibernate.QueryException;
import org.hibernate.ScrollableResults; import org.hibernate.ScrollableResults;
import org.hibernate.SessionException; import org.hibernate.SessionException;
import org.hibernate.StaleObjectStateException;
import org.hibernate.StaleStateException;
import org.hibernate.Transaction; import org.hibernate.Transaction;
import org.hibernate.TransactionException;
import org.hibernate.TransientObjectException;
import org.hibernate.UnresolvableObjectException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.lock.LockingStrategyException;
import org.hibernate.dialect.lock.OptimisticEntityLockException;
import org.hibernate.dialect.lock.PessimisticEntityLockException;
import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.internal.SessionEventListenerManagerImpl; import org.hibernate.engine.internal.SessionEventListenerManagerImpl;
import org.hibernate.engine.jdbc.LobCreationContext; import org.hibernate.engine.jdbc.LobCreationContext;
@ -71,6 +50,7 @@ import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn; import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.ExceptionConverter;
import org.hibernate.engine.spi.NamedQueryDefinition; import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition; import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.QueryParameters;
@ -147,6 +127,8 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
private transient Boolean useStreamForLobBinding; private transient Boolean useStreamForLobBinding;
private transient long timestamp; private transient long timestamp;
protected transient ExceptionConverter exceptionConverter;
public AbstractSharedSessionContract(SessionFactoryImpl factory, SessionCreationOptions options) { public AbstractSharedSessionContract(SessionFactoryImpl factory, SessionCreationOptions options) {
this.factory = factory; this.factory = factory;
this.sessionIdentifier = StandardRandomStrategy.INSTANCE.generateUUID( null ); this.sessionIdentifier = StandardRandomStrategy.INSTANCE.generateUUID( null );
@ -212,6 +194,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
.getService( TransactionCoordinatorBuilder.class ) .getService( TransactionCoordinatorBuilder.class )
.buildTransactionCoordinator( jdbcCoordinator, this ); .buildTransactionCoordinator( jdbcCoordinator, this );
} }
exceptionConverter = new ExceptionConverterImpl( this );
} }
protected void addSharedSessionTransactionObserver(TransactionCoordinator transactionCoordinator) { protected void addSharedSessionTransactionObserver(TransactionCoordinator transactionCoordinator) {
@ -377,7 +360,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
} }
if ( this.currentHibernateTransaction == null ) { if ( this.currentHibernateTransaction == null ) {
this.currentHibernateTransaction = new TransactionImpl( getTransactionCoordinator() ); this.currentHibernateTransaction = new TransactionImpl(
getTransactionCoordinator(),
getExceptionConverter()
);
} }
if ( !isClosed() ) { if ( !isClosed() ) {
getTransactionCoordinator().pulse(); getTransactionCoordinator().pulse();
@ -389,7 +375,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
checkOpen(); checkOpen();
if ( this.currentHibernateTransaction == null || this.currentHibernateTransaction.getStatus() != TransactionStatus.ACTIVE ) { if ( this.currentHibernateTransaction == null || this.currentHibernateTransaction.getStatus() != TransactionStatus.ACTIVE ) {
this.currentHibernateTransaction = new TransactionImpl( getTransactionCoordinator() ); this.currentHibernateTransaction = new TransactionImpl(
getTransactionCoordinator(),
getExceptionConverter()
);
} }
getTransactionCoordinator().pulse(); getTransactionCoordinator().pulse();
return currentHibernateTransaction; return currentHibernateTransaction;
@ -484,7 +473,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return callback.executeOnConnection( connection ); return callback.executeOnConnection( connection );
} }
catch (SQLException e) { catch (SQLException e) {
throw convert( throw exceptionConverter.convert(
e, e,
"Error creating contextual LOB : " + e.getMessage() "Error creating contextual LOB : " + e.getMessage()
); );
@ -565,7 +554,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return createNativeQuery( nativeQueryDefinition ); return createNativeQuery( nativeQueryDefinition );
} }
throw convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) ); throw exceptionConverter.convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) );
} }
protected QueryImplementor createQuery(NamedQueryDefinition queryDefinition) { protected QueryImplementor createQuery(NamedQueryDefinition queryDefinition) {
@ -650,7 +639,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return query; return query;
} }
catch (RuntimeException e) { catch (RuntimeException e) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -671,7 +660,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return query; return query;
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -748,7 +737,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return (QueryImplementor<T>) createNativeQuery( nativeQueryDefinition, resultType ); return (QueryImplementor<T>) createNativeQuery( nativeQueryDefinition, resultType );
} }
throw convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) ); throw exceptionConverter.convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) );
} }
@SuppressWarnings({"WeakerAccess", "unchecked"}) @SuppressWarnings({"WeakerAccess", "unchecked"})
@ -859,7 +848,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return query; return query;
} }
catch ( RuntimeException he ) { catch ( RuntimeException he ) {
throw convert( he ); throw exceptionConverter.convert( he );
} }
} }
@ -875,7 +864,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return query; return query;
} }
catch ( RuntimeException he ) { catch ( RuntimeException he ) {
throw convert( he ); throw exceptionConverter.convert( he );
} }
} }
@ -891,7 +880,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return query; return query;
} }
catch ( RuntimeException he ) { catch ( RuntimeException he ) {
throw convert( he ); throw exceptionConverter.convert( he );
} }
} }
@ -906,7 +895,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return createNativeQuery( nativeQueryDefinition ); return createNativeQuery( nativeQueryDefinition );
} }
throw convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) ); throw exceptionConverter.convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) );
} }
@Override @Override
@ -962,193 +951,6 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return procedureCall; return procedureCall;
} }
protected JDBCException convert(SQLException e, String message) {
return getJdbcServices().getSqlExceptionHelper().convert( e, message );
}
public RuntimeException convert(HibernateException e) {
return convert( e, null );
}
public RuntimeException convert(RuntimeException e) {
RuntimeException result = e;
if ( e instanceof HibernateException ) {
result = convert( (HibernateException) e );
}
else {
markForRollbackOnly();
}
return result;
}
public void handlePersistenceException(PersistenceException e) {
if ( e instanceof NoResultException ) {
return;
}
if ( e instanceof NonUniqueResultException ) {
return;
}
if ( e instanceof LockTimeoutException ) {
return;
}
if ( e instanceof QueryTimeoutException ) {
return;
}
try {
markForRollbackOnly();
}
catch ( Exception ne ) {
//we do not want the subsequent exception to swallow the original one
log.unableToMarkForRollbackOnPersistenceException(ne);
}
}
public void throwPersistenceException(PersistenceException e) {
throw convert( e );
}
public void throwPersistenceException(HibernateException e) {
throw convert( e );
}
public RuntimeException convert(HibernateException e, LockOptions lockOptions) {
Throwable cause = e;
if(e instanceof TransactionException ){
cause = e.getCause();
}
if ( cause instanceof StaleStateException ) {
final PersistenceException converted = wrapStaleStateException( (StaleStateException) cause );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof LockingStrategyException ) {
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.exception.LockTimeoutException ) {
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.PessimisticLockException ) {
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.QueryTimeoutException ) {
final QueryTimeoutException converted = new QueryTimeoutException( cause.getMessage(), cause );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof ObjectNotFoundException ) {
final EntityNotFoundException converted = new EntityNotFoundException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.NonUniqueObjectException ) {
final EntityExistsException converted = new EntityExistsException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.NonUniqueResultException ) {
final NonUniqueResultException converted = new NonUniqueResultException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof UnresolvableObjectException ) {
final EntityNotFoundException converted = new EntityNotFoundException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof QueryException ) {
return new IllegalArgumentException( cause );
}
else if ( cause instanceof TransientObjectException ) {
try {
markForRollbackOnly();
}
catch ( Exception ne ) {
//we do not want the subsequent exception to swallow the original one
log.unableToMarkForRollbackOnTransientObjectException( ne );
}
return new IllegalStateException( e ); //Spec 3.2.3 Synchronization rules
}
else {
final PersistenceException converted = new PersistenceException( cause );
handlePersistenceException( converted );
return converted;
}
}
public PersistenceException wrapLockException(HibernateException e, LockOptions lockOptions) {
final PersistenceException pe;
if ( e instanceof OptimisticEntityLockException ) {
final OptimisticEntityLockException lockException = (OptimisticEntityLockException) e;
pe = new OptimisticLockException( lockException.getMessage(), lockException, lockException.getEntity() );
}
else if ( e instanceof org.hibernate.exception.LockTimeoutException ) {
pe = new LockTimeoutException( e.getMessage(), e, null );
}
else if ( e instanceof PessimisticEntityLockException ) {
final PessimisticEntityLockException lockException = (PessimisticEntityLockException) e;
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
// assume lock timeout occurred if a timeout or NO WAIT was specified
pe = new LockTimeoutException( lockException.getMessage(), lockException, lockException.getEntity() );
}
else {
pe = new PessimisticLockException( lockException.getMessage(), lockException, lockException.getEntity() );
}
}
else if ( e instanceof org.hibernate.PessimisticLockException ) {
final org.hibernate.PessimisticLockException jdbcLockException = (org.hibernate.PessimisticLockException) e;
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
// assume lock timeout occurred if a timeout or NO WAIT was specified
pe = new LockTimeoutException( jdbcLockException.getMessage(), jdbcLockException, null );
}
else {
pe = new PessimisticLockException( jdbcLockException.getMessage(), jdbcLockException, null );
}
}
else {
pe = new OptimisticLockException( e );
}
return pe;
}
public PersistenceException wrapStaleStateException(StaleStateException e) {
PersistenceException pe;
if ( e instanceof StaleObjectStateException ) {
final StaleObjectStateException sose = (StaleObjectStateException) e;
final Serializable identifier = sose.getIdentifier();
if ( identifier != null ) {
try {
final Object entity = load( sose.getEntityName(), identifier );
if ( entity instanceof Serializable ) {
//avoid some user errors regarding boundary crossing
pe = new OptimisticLockException( e.getMessage(), e, entity );
}
else {
pe = new OptimisticLockException( e.getMessage(), e );
}
}
catch ( EntityNotFoundException enfe ) {
pe = new OptimisticLockException( e.getMessage(), e );
}
}
else {
pe = new OptimisticLockException( e.getMessage(), e );
}
}
else {
pe = new OptimisticLockException( e.getMessage(), e );
}
return pe;
}
protected abstract Object load(String entityName, Serializable identifier); protected abstract Object load(String entityName, Serializable identifier);
@Override @Override
@ -1161,6 +963,11 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return scrollCustomQuery( getNativeQueryPlan( spec ).getCustomQuery(), queryParameters ); return scrollCustomQuery( getNativeQueryPlan( spec ).getCustomQuery(), queryParameters );
} }
@Override
public ExceptionConverter getExceptionConverter(){
return exceptionConverter;
}
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void writeObject(ObjectOutputStream oos) throws IOException { private void writeObject(ObjectOutputStream oos) throws IOException {
log.trace( "Serializing " + getClass().getSimpleName() + " [" ); log.trace( "Serializing " + getClass().getSimpleName() + " [" );

View File

@ -0,0 +1,279 @@
/*
* 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;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityNotFoundException;
import javax.persistence.LockTimeoutException;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.persistence.PessimisticLockException;
import javax.persistence.QueryTimeoutException;
import javax.persistence.RollbackException;
import java.io.Serializable;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.JDBCException;
import org.hibernate.LockOptions;
import org.hibernate.ObjectNotFoundException;
import org.hibernate.QueryException;
import org.hibernate.StaleObjectStateException;
import org.hibernate.StaleStateException;
import org.hibernate.TransientObjectException;
import org.hibernate.UnresolvableObjectException;
import org.hibernate.dialect.lock.LockingStrategyException;
import org.hibernate.dialect.lock.OptimisticEntityLockException;
import org.hibernate.dialect.lock.PessimisticEntityLockException;
import org.hibernate.engine.spi.ExceptionConverter;
import org.hibernate.loader.MultipleBagFetchException;
/**
* @author Andrea Boriero
*/
public class ExceptionConverterImpl implements ExceptionConverter {
private static final EntityManagerMessageLogger log = HEMLogging.messageLogger( ExceptionConverterImpl.class );
private final AbstractSharedSessionContract sharedSessionContract;
public ExceptionConverterImpl(AbstractSharedSessionContract sharedSessionContract) {
this.sharedSessionContract = sharedSessionContract;
}
@Override
public RuntimeException convertCommitException(RuntimeException e) {
if ( sharedSessionContract.getFactory().getSessionFactoryOptions().isJpaBootstrap() ) {
Throwable wrappedException;
if ( e instanceof PersistenceException ) {
Throwable cause = e.getCause() == null ? e : e.getCause();
if ( cause instanceof HibernateException ) {
wrappedException = convert( (HibernateException) cause );
}
else {
wrappedException = cause;
}
}
else if ( e instanceof HibernateException ) {
wrappedException = convert( (HibernateException) e );
}
else {
wrappedException = e;
}
try {
//as per the spec we should rollback if commit fails
sharedSessionContract.getTransaction().rollback();
}
catch (Exception re) {
//swallow
}
return new RollbackException( "Error while committing the transaction", wrappedException );
}
else {
return e;
}
}
@Override
public RuntimeException convert(HibernateException e, LockOptions lockOptions) {
Throwable cause = e;
if ( cause instanceof StaleStateException ) {
final PersistenceException converted = wrapStaleStateException( (StaleStateException) cause );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof LockingStrategyException ) {
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.exception.LockTimeoutException ) {
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.PessimisticLockException ) {
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.QueryTimeoutException ) {
final QueryTimeoutException converted = new QueryTimeoutException( cause.getMessage(), cause );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof ObjectNotFoundException ) {
final EntityNotFoundException converted = new EntityNotFoundException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.NonUniqueObjectException ) {
final EntityExistsException converted = new EntityExistsException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.NonUniqueResultException ) {
final NonUniqueResultException converted = new NonUniqueResultException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof UnresolvableObjectException ) {
final EntityNotFoundException converted = new EntityNotFoundException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof QueryException ) {
return new IllegalArgumentException( cause );
}
else if ( cause instanceof MultipleBagFetchException ) {
return new IllegalArgumentException( cause );
}
else if ( cause instanceof TransientObjectException ) {
try {
sharedSessionContract.markForRollbackOnly();
}
catch (Exception ne) {
//we do not want the subsequent exception to swallow the original one
log.unableToMarkForRollbackOnTransientObjectException( ne );
}
return new IllegalStateException( e ); //Spec 3.2.3 Synchronization rules
}
else {
final PersistenceException converted = new PersistenceException( cause );
handlePersistenceException( converted );
return converted;
}
}
@Override
public RuntimeException convert(HibernateException e) {
return convert( e, null );
}
@Override
public RuntimeException convert(RuntimeException e) {
RuntimeException result = e;
if ( e instanceof HibernateException ) {
result = convert( (HibernateException) e );
}
else {
sharedSessionContract.markForRollbackOnly();
}
return result;
}
@Override
public RuntimeException convert(RuntimeException e, LockOptions lockOptions) {
RuntimeException result = e;
if ( e instanceof HibernateException ) {
result = convert( (HibernateException) e, lockOptions );
}
else {
sharedSessionContract.markForRollbackOnly();
}
return result;
}
@Override
public JDBCException convert(SQLException e, String message) {
return sharedSessionContract.getJdbcServices().getSqlExceptionHelper().convert( e, message );
}
protected PersistenceException wrapStaleStateException(StaleStateException e) {
PersistenceException pe;
if ( e instanceof StaleObjectStateException ) {
final StaleObjectStateException sose = (StaleObjectStateException) e;
final Serializable identifier = sose.getIdentifier();
if ( identifier != null ) {
try {
final Object entity = sharedSessionContract.load( sose.getEntityName(), identifier );
if ( entity instanceof Serializable ) {
//avoid some user errors regarding boundary crossing
pe = new OptimisticLockException( e.getMessage(), e, entity );
}
else {
pe = new OptimisticLockException( e.getMessage(), e );
}
}
catch (EntityNotFoundException enfe) {
pe = new OptimisticLockException( e.getMessage(), e );
}
}
else {
pe = new OptimisticLockException( e.getMessage(), e );
}
}
else {
pe = new OptimisticLockException( e.getMessage(), e );
}
return pe;
}
protected PersistenceException wrapLockException(HibernateException e, LockOptions lockOptions) {
final PersistenceException pe;
if ( e instanceof OptimisticEntityLockException ) {
final OptimisticEntityLockException lockException = (OptimisticEntityLockException) e;
pe = new OptimisticLockException( lockException.getMessage(), lockException, lockException.getEntity() );
}
else if ( e instanceof org.hibernate.exception.LockTimeoutException ) {
pe = new LockTimeoutException( e.getMessage(), e, null );
}
else if ( e instanceof PessimisticEntityLockException ) {
final PessimisticEntityLockException lockException = (PessimisticEntityLockException) e;
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
// assume lock timeout occurred if a timeout or NO WAIT was specified
pe = new LockTimeoutException( lockException.getMessage(), lockException, lockException.getEntity() );
}
else {
pe = new PessimisticLockException(
lockException.getMessage(),
lockException,
lockException.getEntity()
);
}
}
else if ( e instanceof org.hibernate.PessimisticLockException ) {
final org.hibernate.PessimisticLockException jdbcLockException = (org.hibernate.PessimisticLockException) e;
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
// assume lock timeout occurred if a timeout or NO WAIT was specified
pe = new LockTimeoutException( jdbcLockException.getMessage(), jdbcLockException, null );
}
else {
pe = new PessimisticLockException( jdbcLockException.getMessage(), jdbcLockException, null );
}
}
else {
pe = new OptimisticLockException( e );
}
return pe;
}
private void handlePersistenceException(PersistenceException e) {
if ( e instanceof NoResultException ) {
return;
}
if ( e instanceof NonUniqueResultException ) {
return;
}
if ( e instanceof LockTimeoutException ) {
return;
}
if ( e instanceof QueryTimeoutException ) {
return;
}
try {
sharedSessionContract.markForRollbackOnly();
}
catch (Exception ne) {
//we do not want the subsequent exception to swallow the original one
log.unableToMarkForRollbackOnPersistenceException( ne );
}
}
}

View File

@ -29,20 +29,13 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.persistence.CacheRetrieveMode; import javax.persistence.CacheRetrieveMode;
import javax.persistence.CacheStoreMode; import javax.persistence.CacheStoreMode;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityGraph; import javax.persistence.EntityGraph;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException; import javax.persistence.EntityNotFoundException;
import javax.persistence.FlushModeType; import javax.persistence.FlushModeType;
import javax.persistence.LockModeType; import javax.persistence.LockModeType;
import javax.persistence.LockTimeoutException;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import javax.persistence.PessimisticLockException;
import javax.persistence.PessimisticLockScope; import javax.persistence.PessimisticLockScope;
import javax.persistence.QueryTimeoutException;
import javax.persistence.StoredProcedureQuery; import javax.persistence.StoredProcedureQuery;
import javax.persistence.TransactionRequiredException; import javax.persistence.TransactionRequiredException;
import javax.persistence.Tuple; import javax.persistence.Tuple;
@ -75,8 +68,6 @@ import org.hibernate.SessionEventListener;
import org.hibernate.SessionException; import org.hibernate.SessionException;
import org.hibernate.SharedSessionBuilder; import org.hibernate.SharedSessionBuilder;
import org.hibernate.SimpleNaturalIdLoadAccess; import org.hibernate.SimpleNaturalIdLoadAccess;
import org.hibernate.StaleObjectStateException;
import org.hibernate.StaleStateException;
import org.hibernate.TransientObjectException; import org.hibernate.TransientObjectException;
import org.hibernate.TypeHelper; import org.hibernate.TypeHelper;
import org.hibernate.TypeMismatchException; import org.hibernate.TypeMismatchException;
@ -84,9 +75,6 @@ import org.hibernate.UnknownProfileException;
import org.hibernate.UnresolvableObjectException; import org.hibernate.UnresolvableObjectException;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.criterion.NaturalIdentifier; import org.hibernate.criterion.NaturalIdentifier;
import org.hibernate.dialect.lock.LockingStrategyException;
import org.hibernate.dialect.lock.OptimisticEntityLockException;
import org.hibernate.dialect.lock.PessimisticEntityLockException;
import org.hibernate.engine.internal.StatefulPersistenceContext; import org.hibernate.engine.internal.StatefulPersistenceContext;
import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator; import org.hibernate.engine.jdbc.NonContextualLobCreator;
@ -161,7 +149,6 @@ import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
import org.hibernate.jpa.internal.util.LockModeTypeHelper; import org.hibernate.jpa.internal.util.LockModeTypeHelper;
import org.hibernate.jpa.spi.CriteriaQueryTupleTransformer; import org.hibernate.jpa.spi.CriteriaQueryTupleTransformer;
import org.hibernate.jpa.spi.HibernateEntityManagerImplementor; import org.hibernate.jpa.spi.HibernateEntityManagerImplementor;
import org.hibernate.loader.MultipleBagFetchException;
import org.hibernate.loader.criteria.CriteriaLoader; import org.hibernate.loader.criteria.CriteriaLoader;
import org.hibernate.loader.custom.CustomLoader; import org.hibernate.loader.custom.CustomLoader;
import org.hibernate.loader.custom.CustomQuery; import org.hibernate.loader.custom.CustomQuery;
@ -253,7 +240,6 @@ public final class SessionImpl
private transient LoadEvent loadEvent; //cached LoadEvent instance private transient LoadEvent loadEvent; //cached LoadEvent instance
public SessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) { public SessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) {
super( factory, options ); super( factory, options );
@ -381,7 +367,7 @@ public final class SessionImpl
internalClear(); internalClear();
} }
catch (RuntimeException e) { catch (RuntimeException e) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -454,8 +440,7 @@ public final class SessionImpl
return !isClosed(); return !isClosed();
} }
catch (HibernateException he) { catch (HibernateException he) {
throwPersistenceException( he ); throw exceptionConverter.convert( he );
return false;
} }
} }
@ -764,17 +749,17 @@ public final class SessionImpl
} }
} }
catch (MappingException e) { catch (MappingException e) {
throw convert( new IllegalArgumentException( e.getMessage() ) ); throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage() ) );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
finally { finally {
try { try {
checkNoUnresolvedActionsAfterOperation(); checkNoUnresolvedActionsAfterOperation();
} }
catch (RuntimeException e) { catch (RuntimeException e) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
} }
@ -789,10 +774,10 @@ public final class SessionImpl
} }
} }
catch ( MappingException e ) { catch ( MappingException e ) {
throw convert( new IllegalArgumentException( e.getMessage() ) ) ; throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage() ) ) ;
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
finally { finally {
delayedAfterCompletion(); delayedAfterCompletion();
@ -866,14 +851,14 @@ public final class SessionImpl
checkNoUnresolvedActionsAfterOperation(); checkNoUnresolvedActionsAfterOperation();
} }
catch ( ObjectDeletedException sse ) { catch ( ObjectDeletedException sse ) {
throw convert( new IllegalArgumentException( sse ) ); throw exceptionConverter.convert( new IllegalArgumentException( sse ) );
} }
catch ( MappingException e ) { catch ( MappingException e ) {
throw convert( new IllegalArgumentException( e.getMessage(), e ) ); throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage(), e ) );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
//including HibernateException //including HibernateException
throw convert( e ); throw exceptionConverter.convert( e );
} }
return event.getResult(); return event.getResult();
@ -889,14 +874,14 @@ public final class SessionImpl
} }
} }
catch ( ObjectDeletedException sse ) { catch ( ObjectDeletedException sse ) {
throw convert( new IllegalArgumentException( sse ) ); throw exceptionConverter.convert( new IllegalArgumentException( sse ) );
} }
catch ( MappingException e ) { catch ( MappingException e ) {
throw convert( new IllegalArgumentException( e.getMessage(), e ) ); throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage(), e ) );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
//including HibernateException //including HibernateException
throw convert( e ); throw exceptionConverter.convert( e );
} }
finally { finally {
delayedAfterCompletion(); delayedAfterCompletion();
@ -1256,7 +1241,7 @@ public final class SessionImpl
} }
} }
//including HibernateException //including HibernateException
throw convert( e ); throw exceptionConverter.convert( e );
} }
finally { finally {
delayedAfterCompletion(); delayedAfterCompletion();
@ -1273,14 +1258,7 @@ public final class SessionImpl
delayedAfterCompletion(); delayedAfterCompletion();
} }
catch (RuntimeException e) { catch (RuntimeException e) {
if ( !getSessionFactory().getSessionFactoryOptions().isJpaBootstrap() ) { throw exceptionConverter.convert( e );
if ( e instanceof HibernateException ) {
handlePersistenceException( (HibernateException) e );
throw e;
}
}
//including HibernateException
throw convert( e );
} }
finally { finally {
delayedAfterCompletion(); delayedAfterCompletion();
@ -1386,7 +1364,7 @@ public final class SessionImpl
delayedAfterCompletion(); delayedAfterCompletion();
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -1983,7 +1961,7 @@ public final class SessionImpl
throw new IllegalArgumentException( e.getMessage(), e ); throw new IllegalArgumentException( e.getMessage(), e );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -2037,7 +2015,7 @@ public final class SessionImpl
throw new IllegalArgumentException( e.getMessage(), e ); throw new IllegalArgumentException( e.getMessage(), e );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3157,208 +3135,6 @@ public final class SessionImpl
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// HibernateEntityManagerImplementor impl // HibernateEntityManagerImplementor impl
@Override
public void handlePersistenceException(PersistenceException e) {
if ( e instanceof NoResultException ) {
return;
}
if ( e instanceof NonUniqueResultException ) {
return;
}
if ( e instanceof LockTimeoutException ) {
return;
}
if ( e instanceof QueryTimeoutException ) {
return;
}
try {
markForRollbackOnly();
}
catch ( Exception ne ) {
//we do not want the subsequent exception to swallow the original one
log.unableToMarkForRollbackOnPersistenceException( ne );
}
}
@Override
public void throwPersistenceException(PersistenceException e) {
throw convert( e );
}
@Override
public RuntimeException convert(HibernateException e, LockOptions lockOptions) {
Throwable cause = e;
// if (e instanceof TransactionException){
// cause = e.getCause();
// }
if ( cause instanceof StaleStateException ) {
final PersistenceException converted = wrapStaleStateException( (StaleStateException) cause );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof LockingStrategyException ) {
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.exception.LockTimeoutException ) {
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.PessimisticLockException ) {
final PersistenceException converted = wrapLockException( (HibernateException) cause, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.QueryTimeoutException ) {
final QueryTimeoutException converted = new QueryTimeoutException( cause.getMessage(), cause );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof ObjectNotFoundException ) {
final EntityNotFoundException converted = new EntityNotFoundException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.NonUniqueObjectException ) {
final EntityExistsException converted = new EntityExistsException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof org.hibernate.NonUniqueResultException ) {
final NonUniqueResultException converted = new NonUniqueResultException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof UnresolvableObjectException ) {
final EntityNotFoundException converted = new EntityNotFoundException( cause.getMessage() );
handlePersistenceException( converted );
return converted;
}
else if ( cause instanceof QueryException ) {
return new IllegalArgumentException( cause );
}
else if ( cause instanceof MultipleBagFetchException ) {
return new IllegalArgumentException( cause );
}
else if ( cause instanceof TransientObjectException ) {
try {
markForRollbackOnly();
}
catch ( Exception ne ) {
//we do not want the subsequent exception to swallow the original one
log.unableToMarkForRollbackOnTransientObjectException( ne );
}
return new IllegalStateException( e ); //Spec 3.2.3 Synchronization rules
}
else {
final PersistenceException converted = new PersistenceException( cause );
handlePersistenceException( converted );
return converted;
}
}
public PersistenceException wrapLockException(HibernateException e, LockOptions lockOptions) {
final PersistenceException pe;
if ( e instanceof OptimisticEntityLockException ) {
final OptimisticEntityLockException lockException = (OptimisticEntityLockException) e;
pe = new OptimisticLockException( lockException.getMessage(), lockException, lockException.getEntity() );
}
else if ( e instanceof org.hibernate.exception.LockTimeoutException ) {
pe = new LockTimeoutException( e.getMessage(), e, null );
}
else if ( e instanceof PessimisticEntityLockException ) {
final PessimisticEntityLockException lockException = (PessimisticEntityLockException) e;
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
// assume lock timeout occurred if a timeout or NO WAIT was specified
pe = new LockTimeoutException( lockException.getMessage(), lockException, lockException.getEntity() );
}
else {
pe = new PessimisticLockException( lockException.getMessage(), lockException, lockException.getEntity() );
}
}
else if ( e instanceof org.hibernate.PessimisticLockException ) {
final org.hibernate.PessimisticLockException jdbcLockException = (org.hibernate.PessimisticLockException) e;
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
// assume lock timeout occurred if a timeout or NO WAIT was specified
pe = new LockTimeoutException( jdbcLockException.getMessage(), jdbcLockException, null );
}
else {
pe = new PessimisticLockException( jdbcLockException.getMessage(), jdbcLockException, null );
}
}
else {
pe = new OptimisticLockException( e );
}
return pe;
}
@Override
public RuntimeException convert(HibernateException e) {
return convert( e, null );
}
public RuntimeException convert(RuntimeException e) {
RuntimeException result = e;
if ( e instanceof HibernateException ) {
result = convert( (HibernateException) e );
}
else {
markForRollbackOnly();
}
return result;
}
public RuntimeException convert(RuntimeException e, LockOptions lockOptions) {
RuntimeException result = e;
if ( e instanceof HibernateException ) {
result = convert( (HibernateException) e , lockOptions );
}
else {
markForRollbackOnly();
}
return result;
}
@Override
public void throwPersistenceException(HibernateException e) {
throw convert( e );
}
@Override
public PersistenceException wrapStaleStateException(StaleStateException e) {
PersistenceException pe;
if ( e instanceof StaleObjectStateException ) {
final StaleObjectStateException sose = (StaleObjectStateException) e;
final Serializable identifier = sose.getIdentifier();
if ( identifier != null ) {
try {
final Object entity = load( sose.getEntityName(), identifier );
if ( entity instanceof Serializable ) {
//avoid some user errors regarding boundary crossing
pe = new OptimisticLockException( e.getMessage(), e, entity );
}
else {
pe = new OptimisticLockException( e.getMessage(), e );
}
}
catch ( EntityNotFoundException enfe ) {
pe = new OptimisticLockException( e.getMessage(), e );
}
}
else {
pe = new OptimisticLockException( e.getMessage(), e );
}
}
else {
pe = new OptimisticLockException( e.getMessage(), e );
}
return pe;
}
@Override @Override
public LockOptions getLockRequest(LockModeType lockModeType, Map<String, Object> properties) { public LockOptions getLockRequest(LockModeType lockModeType, Map<String, Object> properties) {
@ -3444,7 +3220,7 @@ public final class SessionImpl
return query; return query;
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3460,11 +3236,11 @@ public final class SessionImpl
delete( entity ); delete( entity );
} }
catch (MappingException e) { catch (MappingException e) {
throw convert( new IllegalArgumentException( e.getMessage(), e ) ); throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage(), e ) );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
//including HibernateException //including HibernateException
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3527,10 +3303,10 @@ public final class SessionImpl
throw new IllegalArgumentException( e.getMessage(), e ); throw new IllegalArgumentException( e.getMessage(), e );
} }
catch ( MappingException | TypeMismatchException | ClassCastException e ) { catch ( MappingException | TypeMismatchException | ClassCastException e ) {
throw convert( new IllegalArgumentException( e.getMessage(), e ) ); throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage(), e ) );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e, lockOptions ); throw exceptionConverter.convert( e, lockOptions );
} }
finally { finally {
getLoadQueryInfluencers().setFetchGraph( null ); getLoadQueryInfluencers().setFetchGraph( null );
@ -3578,10 +3354,10 @@ public final class SessionImpl
return byId( entityClass ).getReference( (Serializable) primaryKey ); return byId( entityClass ).getReference( (Serializable) primaryKey );
} }
catch ( MappingException | TypeMismatchException | ClassCastException e ) { catch ( MappingException | TypeMismatchException | ClassCastException e ) {
throw convert( new IllegalArgumentException( e.getMessage(), e ) ); throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage(), e ) );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3604,7 +3380,7 @@ public final class SessionImpl
buildLockRequest( lockOptions ).lock( entity ); buildLockRequest( lockOptions ).lock( entity );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
throw convert( e, lockOptions ); throw exceptionConverter.convert( e, lockOptions );
} }
} }
@ -3630,7 +3406,7 @@ public final class SessionImpl
setCacheMode( refreshCacheMode ); setCacheMode( refreshCacheMode );
if ( !contains( entity ) ) { if ( !contains( entity ) ) {
throw convert ( new IllegalArgumentException( "Entity not managed" ) ); throw exceptionConverter.convert( new IllegalArgumentException( "Entity not managed" ) );
} }
if ( lockModeType != null ) { if ( lockModeType != null ) {
@ -3646,10 +3422,10 @@ public final class SessionImpl
} }
} }
catch (MappingException e) { catch (MappingException e) {
throw convert( new IllegalArgumentException( e.getMessage(), e ) ); throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage(), e ) );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
throw convert( e, lockOptions ); throw exceptionConverter.convert( e, lockOptions );
} }
finally { finally {
setCacheMode( previousCacheMode ); setCacheMode( previousCacheMode );
@ -3663,7 +3439,7 @@ public final class SessionImpl
evict( entity ); evict( entity );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3676,7 +3452,7 @@ public final class SessionImpl
} }
if ( !contains( entity ) ) { if ( !contains( entity ) ) {
throw convert( new IllegalArgumentException( "entity not in the persistence context" ) ); throw exceptionConverter.convert( new IllegalArgumentException( "entity not in the persistence context" ) );
} }
return LockModeTypeHelper.getLockModeType( getCurrentLockMode( entity ) ); return LockModeTypeHelper.getLockModeType( getCurrentLockMode( entity ) );
@ -3719,7 +3495,7 @@ public final class SessionImpl
return (QueryImplementor<T>) criteriaCompiler().compile( (CompilableCriteria) criteriaQuery ); return (QueryImplementor<T>) criteriaCompiler().compile( (CompilableCriteria) criteriaQuery );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3730,7 +3506,7 @@ public final class SessionImpl
return criteriaCompiler().compile( (CompilableCriteria) criteriaUpdate ); return criteriaCompiler().compile( (CompilableCriteria) criteriaUpdate );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3741,7 +3517,7 @@ public final class SessionImpl
return criteriaCompiler().compile( (CompilableCriteria) criteriaDelete ); return criteriaCompiler().compile( (CompilableCriteria) criteriaDelete );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3813,7 +3589,7 @@ public final class SessionImpl
return memento.makeProcedureCall( this ); return memento.makeProcedureCall( this );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3823,7 +3599,7 @@ public final class SessionImpl
return createStoredProcedureCall( procedureName ); return createStoredProcedureCall( procedureName );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3833,7 +3609,7 @@ public final class SessionImpl
return createStoredProcedureCall( procedureName, resultClasses ); return createStoredProcedureCall( procedureName, resultClasses );
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3849,7 +3625,7 @@ public final class SessionImpl
} }
} }
catch ( RuntimeException e ) { catch ( RuntimeException e ) {
throw convert( e ); throw exceptionConverter.convert( e );
} }
} }
@ -3874,7 +3650,7 @@ public final class SessionImpl
throw new TransactionRequiredException( e.getMessage() ); throw new TransactionRequiredException( e.getMessage() );
} }
catch (HibernateException he) { catch (HibernateException he) {
throw convert( he ); throw exceptionConverter.convert( he );
} }
} }

View File

@ -30,7 +30,7 @@ public class ExceptionMapperLegacyJpaImpl implements ExceptionMapper {
@Override @Override
public RuntimeException mapManagedFlushFailure(String message, RuntimeException failure, SessionImplementor session) { public RuntimeException mapManagedFlushFailure(String message, RuntimeException failure, SessionImplementor session) {
if ( HibernateException.class.isInstance( failure ) ) { if ( HibernateException.class.isInstance( failure ) ) {
throw session.convert( failure ); throw session.getExceptionConverter().convert( failure );
} }
if ( PersistenceException.class.isInstance( failure ) ) { if ( PersistenceException.class.isInstance( failure ) ) {
throw failure; throw failure;

View File

@ -59,57 +59,6 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage
*/ */
void markForRollbackOnly(); void markForRollbackOnly();
/**
* Handles marking for rollback and other such operations that need to occur depending on the type of
* exception being handled.
*
* @param e The exception being handled.
*/
void handlePersistenceException(PersistenceException e);
/**
* Delegates to {@link #handlePersistenceException} and then throws the given exception.
*
* @param e The exception being handled and finally thrown.
*/
void throwPersistenceException(PersistenceException e);
/**
* Converts a Hibernate-specific exception into a JPA-specified exception; note that the JPA sepcification makes use
* of exceptions outside its exception hierarchy, though they are all runtime exceptions.
* <p/>
* Any appropriate/needed calls to {@link #handlePersistenceException} are also made.
*
* @param e The Hibernate excepton.
* @param lockOptions The lock options in effect at the time of exception (can be null)
*
* @return The JPA-specified exception
*/
RuntimeException convert(HibernateException e, LockOptions lockOptions);
/**
* Converts a Hibernate-specific exception into a JPA-specified exception; note that the JPA sepcification makes use
* of exceptions outside its exception hierarchy, though they are all runtime exceptions.
* <p/>
* Any appropriate/needed calls to {@link #handlePersistenceException} are also made.
*
* @param e The Hibernate excepton.
*
* @return The JPA-specified exception
*/
RuntimeException convert(HibernateException e);
RuntimeException convert(RuntimeException e);
/**
* Delegates to {@link #convert} and then throws the given exception.
*
* @param e The exception being handled and finally thrown.
*/
void throwPersistenceException(HibernateException e);
PersistenceException wrapStaleStateException(StaleStateException e);
/** /**
* Convert from JPA 2 {@link javax.persistence.LockModeType} & properties into {@link org.hibernate.LockOptions} * Convert from JPA 2 {@link javax.persistence.LockModeType} & properties into {@link org.hibernate.LockOptions}
* *

View File

@ -602,7 +602,7 @@ public class ProcedureCallImpl<R>
registerParameter( (ParameterRegistrationImplementor) registerParameter( position, type, mode ) ); registerParameter( (ParameterRegistrationImplementor) registerParameter( position, type, mode ) );
} }
catch (HibernateException he) { catch (HibernateException he) {
throw getProducer().convert( he ); throw getExceptionConverter().convert( he );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
getProducer().markForRollbackOnly(); getProducer().markForRollbackOnly();
@ -620,7 +620,7 @@ public class ProcedureCallImpl<R>
registerParameter( (ParameterRegistrationImplementor) registerParameter( parameterName, type, mode ) ); registerParameter( (ParameterRegistrationImplementor) registerParameter( parameterName, type, mode ) );
} }
catch (HibernateException he) { catch (HibernateException he) {
throw getProducer().convert( he ); throw getExceptionConverter().convert( he );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
getProducer().markForRollbackOnly(); getProducer().markForRollbackOnly();
@ -642,7 +642,7 @@ public class ProcedureCallImpl<R>
return false; return false;
} }
catch (HibernateException he) { catch (HibernateException he) {
throw getProducer().convert( he ); throw getExceptionConverter().convert( he );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
getProducer().markForRollbackOnly(); getProducer().markForRollbackOnly();
@ -724,7 +724,7 @@ public class ProcedureCallImpl<R>
return -1; return -1;
} }
catch (HibernateException he) { catch (HibernateException he) {
throw getProducer().convert( he ); throw getExceptionConverter().convert( he );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
getProducer().markForRollbackOnly(); getProducer().markForRollbackOnly();
@ -751,7 +751,7 @@ public class ProcedureCallImpl<R>
return null; return null;
} }
catch (HibernateException he) { catch (HibernateException he) {
throw getProducer().convert( he ); throw getExceptionConverter().convert( he );
} }
catch (RuntimeException e) { catch (RuntimeException e) {
getProducer().markForRollbackOnly(); getProducer().markForRollbackOnly();

View File

@ -38,6 +38,7 @@ import org.hibernate.ScrollableResults;
import org.hibernate.TypeMismatchException; import org.hibernate.TypeMismatchException;
import org.hibernate.engine.query.spi.EntityGraphQueryHint; import org.hibernate.engine.query.spi.EntityGraphQueryHint;
import org.hibernate.engine.query.spi.HQLQueryPlan; import org.hibernate.engine.query.spi.HQLQueryPlan;
import org.hibernate.engine.spi.ExceptionConverter;
import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.RowSelection;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -1091,7 +1092,7 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
throw new IllegalArgumentException( e ); throw new IllegalArgumentException( e );
} }
catch (HibernateException he) { catch (HibernateException he) {
throw getProducer().convert( he ); throw getExceptionConverter().convert( he );
} }
finally { finally {
afterQuery(); afterQuery();
@ -1147,7 +1148,7 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
} }
catch ( HibernateException e) { catch ( HibernateException e) {
if ( getProducer().getFactory().getSessionFactoryOptions().isJpaBootstrap() ) { if ( getProducer().getFactory().getSessionFactoryOptions().isJpaBootstrap() ) {
throw getProducer().convert( e ); throw getExceptionConverter().convert( e );
} }
else { else {
throw e; throw e;
@ -1209,4 +1210,8 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
.getHQLQueryPlan( getQueryString(), false, Collections.<String, Filter>emptyMap() ) .getHQLQueryPlan( getQueryString(), false, Collections.<String, Filter>emptyMap() )
.isSelect(); .isSelect();
} }
protected ExceptionConverter getExceptionConverter(){
return producer.getExceptionConverter();
}
} }

View File

@ -16,6 +16,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
@ -48,11 +49,10 @@ public class TransactionCommitFailureTest {
transactionFailureTrigger.set( true ); transactionFailureTrigger.set( true );
em.getTransaction().commit(); em.getTransaction().commit();
} }
catch ( Exception e ) { catch (RollbackException e) {
assertEquals(PersistenceException.class, e.getCause().getClass()); assertEquals( COMMIT_FAILURE, e.getCause().getMessage() );
assertEquals(COMMIT_FAILURE, e.getCause().getMessage()); }
} finally {
finally {
if ( em.getTransaction() != null && em.getTransaction().isActive() ) { if ( em.getTransaction() != null && em.getTransaction().isActive() ) {
em.getTransaction().rollback(); em.getTransaction().rollback();
} }