HHH-15683+HHH-15684 clean up the handling of LockOptions for queries
This contains a change to LockOptions.overlay() which is breaking in principle, but more natural and less fragile. It also deprecates SelectionQuery.setAliasSpecificLockMode() which I believe was added in 6.0 by mistake. The method is an overload of setLockMode() in the rest of the hierarchy.
This commit is contained in:
parent
58ba65f529
commit
02ad34091c
|
@ -432,8 +432,18 @@ public class LockOptions implements Serializable {
|
|||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the given lock options into this instance,
|
||||
* merging the alias-specific lock modes.
|
||||
*/
|
||||
public void overlay(LockOptions lockOptions) {
|
||||
copy( lockOptions, this );
|
||||
setLockMode( lockOptions.getLockMode() );
|
||||
setScope( lockOptions.getScope() );
|
||||
setTimeOut( lockOptions.getTimeOut() );
|
||||
if ( lockOptions.aliasSpecificLockModes != null ) {
|
||||
lockOptions.aliasSpecificLockModes.forEach(this::setAliasSpecificLockMode);
|
||||
}
|
||||
setFollowOnLocking( lockOptions.getFollowOnLocking() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
@ -329,11 +330,6 @@ public class ProcedureCallImpl<R>
|
|||
return queryOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryImplementor<R> setLockMode(String alias, LockMode lockMode) {
|
||||
throw new IllegalStateException( "Cannot set LockMode on a procedure-call" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureParameterMetadataImpl getParameterMetadata() {
|
||||
return parameterMetadata;
|
||||
|
@ -1085,14 +1081,24 @@ public class ProcedureCallImpl<R>
|
|||
throw new PersistenceException( "Unrecognized unwrap type : " + cls.getName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryImplementor<R> setLockMode(String alias, LockMode lockMode) {
|
||||
throw new UnsupportedOperationException( "setLockMode does not apply to procedure calls" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureCallImplementor<R> setLockMode(LockModeType lockMode) {
|
||||
throw new IllegalStateException("jakarta.persistence.Query.setLockMode not valid on jakarta.persistence.StoredProcedureQuery" );
|
||||
throw new UnsupportedOperationException( "setLockMode does not apply to procedure calls" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockModeType getLockMode() {
|
||||
throw new IllegalStateException( "jakarta.persistence.Query.getHibernateFlushMode not valid on jakarta.persistence.StoredProcedureQuery" );
|
||||
throw new UnsupportedOperationException( "getLockMode does not apply to procedure calls" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryImplementor<R> setLockOptions(LockOptions lockOptions) {
|
||||
throw new UnsupportedOperationException( "setLockOptions does not apply to procedure calls" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,9 +39,9 @@ import org.hibernate.type.BasicTypeReference;
|
|||
* </li>
|
||||
* <li>
|
||||
* Tables used via {@link #addSynchronizedQuerySpace}, {@link #addSynchronizedEntityName} and
|
||||
* {@link org.hibernate.query.SynchronizeableQuery#addSynchronizedEntityClass}. This allows Hibernate to know how to properly deal with
|
||||
* auto-flush checking as well as cached query results if the results of the query are being
|
||||
* cached.
|
||||
* {@link org.hibernate.query.SynchronizeableQuery#addSynchronizedEntityClass}. This allows
|
||||
* Hibernate to know how to properly deal with auto-flush checking as well as cached query
|
||||
* results if the results of the query are being cached.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
|
@ -51,7 +51,8 @@ import org.hibernate.type.BasicTypeReference;
|
|||
* of its metadata
|
||||
* </li>
|
||||
* <li>
|
||||
* A pre-defined (defined in metadata and named) mapping can be associated via {@link org.hibernate.Session#createNativeQuery(String, String)}
|
||||
* A pre-defined (defined in metadata and named) mapping can be associated via
|
||||
* {@link org.hibernate.Session#createNativeQuery(String, String)}
|
||||
* </li>
|
||||
* <li>
|
||||
* Defined locally per the various {@link #addEntity}, {@link #addRoot}, {@link #addJoin},
|
||||
|
|
|
@ -317,22 +317,22 @@ public interface Query<R> extends SelectionQuery<R>, MutationQuery, TypedQuery<R
|
|||
/**
|
||||
* Obtains the {@link LockOptions} in effect for this query.
|
||||
*
|
||||
* @return The LockOptions
|
||||
* @return The {@link LockOptions} currently in effect
|
||||
*
|
||||
* @see LockOptions
|
||||
*/
|
||||
@Override
|
||||
LockOptions getLockOptions();
|
||||
|
||||
/**
|
||||
* Set the lock options for the query.
|
||||
* <p>
|
||||
* Only the following options are taken into consideration:
|
||||
* <ol>
|
||||
* <li>{@link LockOptions#getLockMode()}</li>
|
||||
* <li>{@link LockOptions#getScope()}</li>
|
||||
* <li>{@link LockOptions#getTimeOut()}</li>
|
||||
* </ol>
|
||||
* For alias-specific locking, use {@link #setLockMode(String, LockMode)}.
|
||||
* Apply the given {@linkplain LockOptions lock options} to this
|
||||
* query. Alias-specific lock modes in the given lock options are
|
||||
* merged with any alias-specific lock mode which have already been
|
||||
* {@linkplain #setAliasSpecificLockMode(String, LockMode) set}. If
|
||||
* a lock mode has already been specified for an alias that is among
|
||||
* the aliases in the given lock options, the lock mode specified in
|
||||
* the given lock options overrides the lock mode that was already
|
||||
* set.
|
||||
*
|
||||
* @param lockOptions The lock options to apply to the query.
|
||||
*
|
||||
|
@ -353,13 +353,14 @@ public interface Query<R> extends SelectionQuery<R>, MutationQuery, TypedQuery<R
|
|||
* driver and database. For maximum portability, the given lock
|
||||
* mode should be {@link LockMode#PESSIMISTIC_WRITE}.
|
||||
*
|
||||
* @param alias a query alias, or {@code "this"} for a collection filter
|
||||
* @param alias a query alias, or {@code this} for a collection filter
|
||||
* @param lockMode The lock mode to apply.
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*
|
||||
* @see #getLockOptions()
|
||||
*/
|
||||
@Override
|
||||
Query<R> setLockMode(String alias, LockMode lockMode);
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.hibernate.Incubating;
|
|||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.NonUniqueResultException;
|
||||
import org.hibernate.Remove;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.Session;
|
||||
|
@ -324,25 +325,33 @@ public interface SelectionQuery<R> extends CommonQueryContract {
|
|||
SelectionQuery<R> setCacheRegion(String cacheRegion);
|
||||
|
||||
/**
|
||||
* The LockOptions currently in effect for the query
|
||||
* The {@link LockOptions} currently in effect for the query
|
||||
*/
|
||||
LockOptions getLockOptions();
|
||||
|
||||
/**
|
||||
* Specify the root LockModeType for the query
|
||||
* Specify the root {@link LockModeType} for the query
|
||||
*
|
||||
* @see #setHibernateLockMode
|
||||
*/
|
||||
SelectionQuery<R> setLockMode(LockModeType lockMode);
|
||||
|
||||
/**
|
||||
* Specify the root LockMode for the query
|
||||
* Specify the root {@link LockMode} for the query
|
||||
*/
|
||||
SelectionQuery<R> setHibernateLockMode(LockMode lockMode);
|
||||
|
||||
/**
|
||||
* Specify a LockMode to apply to a specific alias defined in the query
|
||||
* Specify a {@link LockMode} to apply to a specific alias defined in the query
|
||||
*/
|
||||
SelectionQuery<R> setLockMode(String alias, LockMode lockMode);
|
||||
|
||||
/**
|
||||
* Specify a {@link LockMode} to apply to a specific alias defined in the query
|
||||
*
|
||||
* @deprecated use {@link #setLockMode(String, LockMode)}
|
||||
*/
|
||||
@Deprecated(since = "6.2") @Remove
|
||||
SelectionQuery<R> setAliasSpecificLockMode(String alias, LockMode lockMode);
|
||||
|
||||
/**
|
||||
|
|
|
@ -247,16 +247,12 @@ public abstract class AbstractQuery<R>
|
|||
@Override
|
||||
public LockModeType getLockMode() {
|
||||
getSession().checkOpen( false );
|
||||
|
||||
return LockModeTypeHelper.getLockModeType( getQueryOptions().getLockOptions().getLockMode() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryImplementor<R> setLockOptions(LockOptions lockOptions) {
|
||||
getQueryOptions().getLockOptions().setLockMode( lockOptions.getLockMode() );
|
||||
getQueryOptions().getLockOptions().setScope( lockOptions.getScope() );
|
||||
getQueryOptions().getLockOptions().setTimeOut( lockOptions.getTimeOut() );
|
||||
getQueryOptions().getLockOptions().setFollowOnLocking( lockOptions.getFollowOnLocking() );
|
||||
getQueryOptions().getLockOptions().overlay( lockOptions );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -585,7 +585,10 @@ public abstract class AbstractSelectionQuery<R>
|
|||
|
||||
/**
|
||||
* Specify a LockMode to apply to a specific alias defined in the query
|
||||
*
|
||||
* @deprecated use {{@link #setLockMode(String, LockMode)}}
|
||||
*/
|
||||
@Override @Deprecated
|
||||
public SelectionQuery<R> setAliasSpecificLockMode(String alias, LockMode lockMode) {
|
||||
getLockOptions().setAliasSpecificLockMode( alias, lockMode );
|
||||
return this;
|
||||
|
|
|
@ -472,24 +472,22 @@ public class NativeQueryImpl<R>
|
|||
|
||||
@Override
|
||||
public LockModeType getLockMode() {
|
||||
throw new IllegalStateException( "Illegal attempt to get lock mode on a native-query" );
|
||||
throw new UnsupportedOperationException( "Illegal attempt to get lock mode on a native-query" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeQueryImplementor<R> setLockOptions(LockOptions lockOptions) {
|
||||
super.setLockOptions( lockOptions );
|
||||
return this;
|
||||
throw new UnsupportedOperationException( "Illegal attempt to set lock options for a native query" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeQueryImplementor<R> setLockMode(String alias, LockMode lockMode) {
|
||||
super.setLockMode( alias, lockMode );
|
||||
return this;
|
||||
throw new UnsupportedOperationException( "Illegal attempt to set lock mode for a native query" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeQueryImplementor<R> setLockMode(LockModeType lockModeType) {
|
||||
throw new IllegalStateException( "Illegal attempt to set lock mode on a native-query" );
|
||||
throw new UnsupportedOperationException( "Illegal attempt to set lock mode for a native query" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -599,10 +597,8 @@ public class NativeQueryImpl<R>
|
|||
private SelectQueryPlan<R> resolveSelectQueryPlan() {
|
||||
final QueryInterpretationCache.Key cacheKey = generateSelectInterpretationsKey( resultSetMapping );
|
||||
if ( cacheKey != null ) {
|
||||
return getSession().getFactory().getQueryEngine().getInterpretationCache().resolveSelectQueryPlan(
|
||||
cacheKey,
|
||||
() -> createQueryPlan( resultSetMapping )
|
||||
);
|
||||
return getSession().getFactory().getQueryEngine().getInterpretationCache()
|
||||
.resolveSelectQueryPlan( cacheKey, () -> createQueryPlan( resultSetMapping ) );
|
||||
}
|
||||
else {
|
||||
return createQueryPlan( resultSetMapping );
|
||||
|
|
|
@ -43,14 +43,10 @@ import jakarta.persistence.metamodel.SingularAttribute;
|
|||
public interface NativeQueryImplementor<R> extends QueryImplementor<R>, NativeQuery<R>, NameableQuery {
|
||||
|
||||
@Override
|
||||
default LockOptions getLockOptions() {
|
||||
return null;
|
||||
}
|
||||
LockOptions getLockOptions();
|
||||
|
||||
@Override
|
||||
default LockModeType getLockMode() {
|
||||
return null;
|
||||
}
|
||||
LockModeType getLockMode();
|
||||
|
||||
/**
|
||||
* Best guess whether this is a select query. {@code null}
|
||||
|
|
|
@ -456,7 +456,7 @@ public class SqmSelectionQueryImpl<R> extends AbstractSelectionQuery<R> implemen
|
|||
}
|
||||
|
||||
/**
|
||||
* Specify the root LockMode for the query
|
||||
* Specify the root {@link LockMode} for the query
|
||||
*/
|
||||
@Override
|
||||
public SqmSelectionQuery<R> setHibernateLockMode(LockMode lockMode) {
|
||||
|
@ -465,10 +465,21 @@ public class SqmSelectionQueryImpl<R> extends AbstractSelectionQuery<R> implemen
|
|||
}
|
||||
|
||||
/**
|
||||
* Specify a LockMode to apply to a specific alias defined in the query
|
||||
* Specify a {@link LockMode} to apply to a specific alias defined in the query
|
||||
*
|
||||
* @deprecated use {{@link #setLockMode(String, LockMode)}}
|
||||
*/
|
||||
@Override @Deprecated
|
||||
public SqmSelectionQuery<R> setAliasSpecificLockMode(String alias, LockMode lockMode) {
|
||||
getLockOptions().setAliasSpecificLockMode( alias, lockMode );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a {@link LockMode} to apply to a specific alias defined in the query
|
||||
*/
|
||||
@Override
|
||||
public SqmSelectionQuery<R> setAliasSpecificLockMode(String alias, LockMode lockMode) {
|
||||
public SqmSelectionQuery<R> setLockMode(String alias, LockMode lockMode) {
|
||||
getLockOptions().setAliasSpecificLockMode( alias, lockMode );
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ public class QueryLockingTest extends BaseEntityManagerFunctionalTestCase {
|
|||
query.setLockMode( LockModeType.READ );
|
||||
fail( "Should have failed" );
|
||||
}
|
||||
catch (IllegalStateException expected) {
|
||||
catch (UnsupportedOperationException expected) {
|
||||
}
|
||||
|
||||
// however, we should be able to set it using hints
|
||||
|
|
Loading…
Reference in New Issue