mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-17 00:24:57 +00:00
HHH-8442 - StoredProcedureQuery.execute() should rollback the TX for certain exceptions
This commit is contained in:
parent
1a59e9194b
commit
e42e786e8d
@ -104,7 +104,7 @@ protected void checkOpen() {
|
||||
public void checkOpen(boolean markForRollbackIfClosed) {
|
||||
if( ! isOpen() ) {
|
||||
if ( markForRollbackIfClosed ) {
|
||||
markAsRollback();
|
||||
markForRollbackOnly();
|
||||
}
|
||||
throw new IllegalStateException( "EntityManager is closed" );
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
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 @@ protected boolean applyFlushModeHint(FlushMode flushMode) {
|
||||
@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 StoredProcedureQuery registerStoredProcedureParameter(int position, Class
|
||||
@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 boolean execute() {
|
||||
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 int executeUpdate() {
|
||||
|
||||
@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 Object getOutputParameterValue(int position) {
|
||||
|
||||
@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 @@ else if ( UpdateCountOutput.class.isInstance( rtn ) ) {
|
||||
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 List getResultList() {
|
||||
// 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 <T> T unwrap(Class<T> clazz) {
|
||||
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 void handlePersistenceException(PersistenceException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
markAsRollback();
|
||||
markForRollbackOnly();
|
||||
}
|
||||
catch ( Exception ne ) {
|
||||
//we do not want the subsequent exception to swallow the original one
|
||||
@ -1537,7 +1538,7 @@ public RuntimeException convert(RuntimeException e) {
|
||||
result = convert( ( HibernateException ) e );
|
||||
}
|
||||
else {
|
||||
markAsRollback();
|
||||
markForRollbackOnly();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1594,7 +1595,7 @@ else if ( e instanceof QueryException ) {
|
||||
}
|
||||
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 <T> BaseQueryImpl setParameter(Parameter<T> param, T value) {
|
||||
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 BaseQueryImpl setParameter(Parameter<Calendar> param, Calendar value, Tem
|
||||
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 BaseQueryImpl setParameter(Parameter<Date> param, Date value, TemporalTyp
|
||||
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 BaseQueryImpl setParameter(String name, Object value) {
|
||||
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 BaseQueryImpl setParameter(String name, Calendar value, TemporalType temp
|
||||
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 BaseQueryImpl setParameter(String name, Date value, TemporalType temporal
|
||||
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 BaseQueryImpl setParameter(int position, Object value) {
|
||||
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 BaseQueryImpl setParameter(int position, Calendar value, TemporalType tem
|
||||
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 BaseQueryImpl setParameter(int position, Date value, TemporalType tempora
|
||||
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…
x
Reference in New Issue
Block a user