HHH-8442 - StoredProcedureQuery.execute() should rollback the TX for certain exceptions
This commit is contained in:
parent
1a59e9194b
commit
e42e786e8d
|
@ -104,7 +104,7 @@ public class EntityManagerImpl extends AbstractEntityManagerImpl implements Sess
|
|||
public void checkOpen(boolean markForRollbackIfClosed) {
|
||||
if( ! isOpen() ) {
|
||||
if ( markForRollbackIfClosed ) {
|
||||
markAsRollback();
|
||||
markForRollbackOnly();
|
||||
}
|
||||
throw new IllegalStateException( "EntityManager is closed" );
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.jpa.spi.ParameterBind;
|
||||
import org.hibernate.jpa.spi.ParameterRegistration;
|
||||
|
@ -122,12 +123,23 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
@SuppressWarnings("unchecked")
|
||||
public StoredProcedureQuery registerStoredProcedureParameter(int position, Class type, ParameterMode mode) {
|
||||
entityManager().checkOpen( true );
|
||||
registerParameter(
|
||||
new ParameterRegistrationImpl(
|
||||
this,
|
||||
procedureCall.registerParameter( position, type, mode )
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
registerParameter(
|
||||
new ParameterRegistrationImpl(
|
||||
this,
|
||||
procedureCall.registerParameter( position, type, mode )
|
||||
)
|
||||
);
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager().convert( he );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
entityManager().markForRollbackOnly();
|
||||
throw e;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -135,12 +147,23 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
@SuppressWarnings("unchecked")
|
||||
public StoredProcedureQuery registerStoredProcedureParameter(String parameterName, Class type, ParameterMode mode) {
|
||||
entityManager().checkOpen( true );
|
||||
registerParameter(
|
||||
new ParameterRegistrationImpl(
|
||||
this,
|
||||
procedureCall.registerParameter( parameterName, type, mode )
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
registerParameter(
|
||||
new ParameterRegistrationImpl(
|
||||
this,
|
||||
procedureCall.registerParameter( parameterName, type, mode )
|
||||
)
|
||||
);
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager().convert( he );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
entityManager().markForRollbackOnly();
|
||||
throw e;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -214,6 +237,13 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
catch (NoMoreReturnsException e) {
|
||||
return false;
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager().convert( he );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
entityManager().markForRollbackOnly();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected ProcedureOutputs outputs() {
|
||||
|
@ -241,6 +271,7 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
|
||||
@Override
|
||||
public Object getOutputParameterValue(int position) {
|
||||
// NOTE : according to spec (specifically), an exception thrown from this method should not mark for rollback.
|
||||
try {
|
||||
return outputs().getOutputParameterValue( position );
|
||||
}
|
||||
|
@ -254,6 +285,7 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
|
||||
@Override
|
||||
public Object getOutputParameterValue(String parameterName) {
|
||||
// NOTE : according to spec (specifically), an exception thrown from this method should not mark for rollback.
|
||||
try {
|
||||
return outputs().getOutputParameterValue( parameterName );
|
||||
}
|
||||
|
@ -287,6 +319,13 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
catch (NoMoreReturnsException e) {
|
||||
return -1;
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager().convert( he );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
entityManager().markForRollbackOnly();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -305,6 +344,13 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
// getResultList was called.
|
||||
return null;
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager().convert( he );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
entityManager().markForRollbackOnly();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1379,7 +1379,8 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
throw new PersistenceException( "Hibernate cannot unwrap " + clazz );
|
||||
}
|
||||
|
||||
protected void markAsRollback() {
|
||||
@Override
|
||||
public void markForRollbackOnly() {
|
||||
LOG.debugf("Mark transaction for rollback");
|
||||
if ( tx.isActive() ) {
|
||||
tx.setRollbackOnly();
|
||||
|
@ -1511,7 +1512,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
}
|
||||
|
||||
try {
|
||||
markAsRollback();
|
||||
markForRollbackOnly();
|
||||
}
|
||||
catch ( Exception ne ) {
|
||||
//we do not want the subsequent exception to swallow the original one
|
||||
|
@ -1537,7 +1538,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
result = convert( ( HibernateException ) e );
|
||||
}
|
||||
else {
|
||||
markAsRollback();
|
||||
markForRollbackOnly();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1594,7 +1595,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
}
|
||||
else if ( e instanceof TransientObjectException ) {
|
||||
try {
|
||||
markAsRollback();
|
||||
markForRollbackOnly();
|
||||
}
|
||||
catch ( Exception ne ) {
|
||||
//we do not want the subsequent exception to swallow the original one
|
||||
|
|
|
@ -491,7 +491,8 @@ public abstract class BaseQueryImpl implements Query {
|
|||
findParameterRegistration( param ).bindValue( value );
|
||||
}
|
||||
catch (QueryParameterException e) {
|
||||
throw new IllegalArgumentException( e );
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager.convert( he );
|
||||
|
@ -508,7 +509,8 @@ public abstract class BaseQueryImpl implements Query {
|
|||
findParameterRegistration( param ).bindValue( value, temporalType );
|
||||
}
|
||||
catch (QueryParameterException e) {
|
||||
throw new IllegalArgumentException( e );
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager.convert( he );
|
||||
|
@ -525,7 +527,8 @@ public abstract class BaseQueryImpl implements Query {
|
|||
findParameterRegistration( param ).bindValue( value, temporalType );
|
||||
}
|
||||
catch (QueryParameterException e) {
|
||||
throw new IllegalArgumentException( e );
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager.convert( he );
|
||||
|
@ -543,7 +546,8 @@ public abstract class BaseQueryImpl implements Query {
|
|||
findParameterRegistration( name ).bindValue( value );
|
||||
}
|
||||
catch (QueryParameterException e) {
|
||||
throw new IllegalArgumentException( e );
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager.convert( he );
|
||||
|
@ -560,7 +564,8 @@ public abstract class BaseQueryImpl implements Query {
|
|||
findParameterRegistration( name ).bindValue( value, temporalType );
|
||||
}
|
||||
catch (QueryParameterException e) {
|
||||
throw new IllegalArgumentException( e );
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager.convert( he );
|
||||
|
@ -577,7 +582,8 @@ public abstract class BaseQueryImpl implements Query {
|
|||
findParameterRegistration( name ).bindValue( value, temporalType );
|
||||
}
|
||||
catch (QueryParameterException e) {
|
||||
throw new IllegalArgumentException( e );
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager.convert( he );
|
||||
|
@ -594,7 +600,8 @@ public abstract class BaseQueryImpl implements Query {
|
|||
findParameterRegistration( position ).bindValue( value );
|
||||
}
|
||||
catch (QueryParameterException e) {
|
||||
throw new IllegalArgumentException( e );
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager.convert( he );
|
||||
|
@ -611,7 +618,8 @@ public abstract class BaseQueryImpl implements Query {
|
|||
findParameterRegistration( position ).bindValue( value, temporalType );
|
||||
}
|
||||
catch (QueryParameterException e) {
|
||||
throw new IllegalArgumentException( e );
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager.convert( he );
|
||||
|
@ -628,13 +636,16 @@ public abstract class BaseQueryImpl implements Query {
|
|||
findParameterRegistration( position ).bindValue( value, temporalType );
|
||||
}
|
||||
catch (ParameterStrategyException e) {
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( "Invalid mix of named and positional parameters", e );
|
||||
}
|
||||
catch (NoSuchParameterException e) {
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (QueryParameterException e) {
|
||||
throw new IllegalArgumentException( e );
|
||||
entityManager().markForRollbackOnly();
|
||||
throw new IllegalArgumentException( e.getMessage(), e );
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw entityManager.convert( he );
|
||||
|
|
|
@ -72,6 +72,11 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage
|
|||
*/
|
||||
boolean isTransactionInProgress();
|
||||
|
||||
/**
|
||||
* Used to mark a transaction for rollback only (when that is the JPA spec defined behavior).
|
||||
*/
|
||||
public void markForRollbackOnly();
|
||||
|
||||
/**
|
||||
* Handles marking for rollback and other such operations that need to occur depending on the type of
|
||||
* exception being handled.
|
||||
|
|
Loading…
Reference in New Issue