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