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