HHH-13262 - javax.persistence.TransactionRequiredException: Executing an update/delete query
This commit is contained in:
parent
4256f300dd
commit
ef3b07bd73
|
@ -157,6 +157,11 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
|
|||
return delegate.isTransactionInProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkTransactionNeededForUpdateOperation(String exceptionMessage) {
|
||||
delegate.checkTransactionNeededForUpdateOperation( exceptionMessage );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockOptions getLockRequest(LockModeType lockModeType, Map<String, Object> properties) {
|
||||
return delegate.getLockRequest( lockModeType, properties );
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.persistence.FlushModeType;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.Criteria;
|
||||
|
@ -180,6 +181,18 @@ public interface SharedSessionContractImplementor
|
|||
*/
|
||||
boolean isTransactionInProgress();
|
||||
|
||||
/**
|
||||
* Check if an active Transaction is necessary for the update operation to be executed.
|
||||
* If an active Transaction is necessary but it is not then a TransactionRequiredException is raised.
|
||||
*
|
||||
* @param exceptionMessage, the message to use for the TransactionRequiredException
|
||||
*/
|
||||
default void checkTransactionNeededForUpdateOperation(String exceptionMessage) {
|
||||
if ( !isTransactionInProgress() ) {
|
||||
throw getExceptionConverter().convert( new TransactionRequiredException( exceptionMessage ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the underlying transaction or creates a new transaction if
|
||||
* one does not already exist or is active. This is primarily for internal or
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.List;
|
|||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
import javax.persistence.FlushModeType;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
import javax.persistence.Tuple;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
|
@ -128,6 +129,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
|
||||
protected boolean closed;
|
||||
protected boolean waitingForAutoClose;
|
||||
private transient boolean disallowOutOfTransactionUpdateOperations;
|
||||
|
||||
// transient & non-final for Serialization purposes - ugh
|
||||
private transient SessionEventListenerManagerImpl sessionEventsManager = new SessionEventListenerManagerImpl();
|
||||
|
@ -141,6 +143,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
public AbstractSharedSessionContract(SessionFactoryImpl factory, SessionCreationOptions options) {
|
||||
this.factory = factory;
|
||||
this.cacheTransactionSync = factory.getCache().getRegionFactory().createTransactionContext( this );
|
||||
this.disallowOutOfTransactionUpdateOperations = !factory.getSessionFactoryOptions().isAllowOutOfTransactionUpdateOperations();
|
||||
|
||||
this.flushMode = options.getInitialSessionFlushMode();
|
||||
|
||||
|
@ -389,6 +392,13 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
return !isClosed() && transactionCoordinator.isTransactionActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkTransactionNeededForUpdateOperation(String exceptionMessage) {
|
||||
if ( disallowOutOfTransactionUpdateOperations && !isTransactionInProgress() ) {
|
||||
throw getExceptionConverter().convert( new TransactionRequiredException( exceptionMessage ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction getTransaction() throws HibernateException {
|
||||
if ( getFactory().getSessionFactoryOptions().getJpaCompliance().isJpaTransactionComplianceEnabled() ) {
|
||||
|
@ -1133,5 +1143,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
|
||||
entityNameResolver = new CoordinatingEntityNameResolver( factory, interceptor );
|
||||
exceptionConverter = new ExceptionConverterImpl( this );
|
||||
this.disallowOutOfTransactionUpdateOperations = !getFactory().getSessionFactoryOptions().isAllowOutOfTransactionUpdateOperations();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,7 +242,6 @@ public final class SessionImpl
|
|||
|
||||
private transient int dontFlushFromFind;
|
||||
|
||||
private transient boolean disallowOutOfTransactionUpdateOperations;
|
||||
private transient ExceptionMapper exceptionMapper;
|
||||
private transient ManagedFlushChecker managedFlushChecker;
|
||||
|
||||
|
@ -266,7 +265,7 @@ public final class SessionImpl
|
|||
this.autoClear = options.shouldAutoClear();
|
||||
this.autoClose = options.shouldAutoClose();
|
||||
this.queryParametersValidationEnabled = options.isQueryParametersValidationEnabled();
|
||||
this.disallowOutOfTransactionUpdateOperations = !factory.getSessionFactoryOptions().isAllowOutOfTransactionUpdateOperations();
|
||||
|
||||
this.discardOnClose = getFactory().getSessionFactoryOptions().isReleaseResourcesOnCloseEnabled();
|
||||
|
||||
if ( options instanceof SharedSessionCreationOptions && ( (SharedSessionCreationOptions) options ).isTransactionCoordinatorShared() ) {
|
||||
|
@ -1471,7 +1470,7 @@ public final class SessionImpl
|
|||
}
|
||||
|
||||
private void doFlush() {
|
||||
checkTransactionNeeded();
|
||||
checkTransactionNeededForUpdateOperation();
|
||||
checkTransactionSynchStatus();
|
||||
|
||||
try {
|
||||
|
@ -3536,7 +3535,7 @@ public final class SessionImpl
|
|||
|
||||
if ( lockModeType != null ) {
|
||||
if ( !LockModeType.NONE.equals( lockModeType) ) {
|
||||
checkTransactionNeeded();
|
||||
checkTransactionNeededForUpdateOperation();
|
||||
}
|
||||
lockOptions = buildLockOptions( lockModeType, properties );
|
||||
loadAccess.with( lockOptions );
|
||||
|
@ -3608,10 +3607,8 @@ public final class SessionImpl
|
|||
return ( CacheStoreMode ) settings.get( JPA_SHARED_CACHE_STORE_MODE );
|
||||
}
|
||||
|
||||
private void checkTransactionNeeded() {
|
||||
if ( disallowOutOfTransactionUpdateOperations && !isTransactionInProgress() ) {
|
||||
throw new TransactionRequiredException( "no transaction is in progress" );
|
||||
}
|
||||
private void checkTransactionNeededForUpdateOperation() {
|
||||
checkTransactionNeededForUpdateOperation( "no transaction is in progress" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3637,7 +3634,7 @@ public final class SessionImpl
|
|||
@Override
|
||||
public void lock(Object entity, LockModeType lockModeType, Map<String, Object> properties) {
|
||||
checkOpen();
|
||||
checkTransactionNeeded();
|
||||
checkTransactionNeededForUpdateOperation();
|
||||
|
||||
if ( !contains( entity ) ) {
|
||||
throw new IllegalArgumentException( "entity not in the persistence context" );
|
||||
|
@ -3679,7 +3676,7 @@ public final class SessionImpl
|
|||
|
||||
if ( lockModeType != null ) {
|
||||
if ( !LockModeType.NONE.equals( lockModeType) ) {
|
||||
checkTransactionNeeded();
|
||||
checkTransactionNeededForUpdateOperation();
|
||||
}
|
||||
|
||||
lockOptions = buildLockOptions( lockModeType, properties );
|
||||
|
@ -4011,7 +4008,6 @@ public final class SessionImpl
|
|||
|
||||
initializeFromSessionOwner( null );
|
||||
|
||||
this.disallowOutOfTransactionUpdateOperations = !getFactory().getSessionFactoryOptions().isAllowOutOfTransactionUpdateOperations();
|
||||
this.discardOnClose = getFactory().getSessionFactoryOptions().isReleaseResourcesOnCloseEnabled();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import javax.persistence.NonUniqueResultException;
|
|||
import javax.persistence.Parameter;
|
||||
import javax.persistence.ParameterMode;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||
|
@ -636,9 +635,8 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
@Override
|
||||
public int executeUpdate() {
|
||||
if ( ! getProducer().isTransactionInProgress() ) {
|
||||
throw new TransactionRequiredException( "javax.persistence.Query.executeUpdate requires active transaction" );
|
||||
}
|
||||
getProducer().checkTransactionNeededForUpdateOperation(
|
||||
"javax.persistence.Query.executeUpdate requires active transaction" );
|
||||
|
||||
// the expectation is that there is just one Output, of type UpdateCountOutput
|
||||
try {
|
||||
|
|
|
@ -1606,13 +1606,8 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
@Override
|
||||
public int executeUpdate() throws HibernateException {
|
||||
if ( ! getProducer().isTransactionInProgress() ) {
|
||||
throw getProducer().getExceptionConverter().convert(
|
||||
new TransactionRequiredException(
|
||||
"Executing an update/delete query"
|
||||
)
|
||||
);
|
||||
}
|
||||
getProducer().checkTransactionNeededForUpdateOperation( "Executing an update/delete query" );
|
||||
|
||||
beforeQuery();
|
||||
try {
|
||||
return doExecuteUpdate();
|
||||
|
|
Loading…
Reference in New Issue