All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.LockOptions Maven / Gradle / Ivy

There is a newer version: 5.6.15.Final
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Contains locking details (LockMode, Timeout and Scope).
 * 
 * @author Scott Marlow
 */
public class LockOptions implements Serializable {
	/**
	 * Represents LockMode.NONE (timeout + scope do not apply).
	 */
	public static final LockOptions NONE = new LockOptions(LockMode.NONE);

	/**
	 * Represents LockMode.READ (timeout + scope do not apply).
	 */
	public static final LockOptions READ = new LockOptions(LockMode.READ);

	/**
	 * Represents LockMode.UPGRADE (will wait forever for lock and scope of false meaning only entity is locked).
	 */
	@SuppressWarnings("deprecation")
	public static final LockOptions UPGRADE = new LockOptions(LockMode.UPGRADE);

	/**
	 * Indicates that the database should not wait at all to acquire the pessimistic lock.
	 * @see #getTimeOut
	 */
	public static final int NO_WAIT = 0;

	/**
	 * Indicates that there is no timeout for the acquisition.
	 * @see #getTimeOut
	 */
	public static final int WAIT_FOREVER = -1;

	/**
	 * Indicates that rows that are already locked should be skipped.
	 * @see #getTimeOut()
	 */
	public static final int SKIP_LOCKED = -2;

	private LockMode lockMode = LockMode.NONE;
	private int timeout = WAIT_FOREVER;

	private Map aliasSpecificLockModes;

	private Boolean followOnLocking;

	/**
	 * Constructs a LockOptions with all default options.
	 */
	public LockOptions() {
	}

	/**
	 * Constructs a LockOptions with the given lock mode.
	 *
	 * @param lockMode The lock mode to use
	 */
	public LockOptions( LockMode lockMode) {
		this.lockMode = lockMode;
	}


	/**
	 * Retrieve the overall lock mode in effect for this set of options.
	 * 

* In certain contexts (hql and criteria), lock-modes can be defined in an * even more granular {@link #setAliasSpecificLockMode(String, LockMode) per-alias} fashion * * @return The overall lock mode. */ public LockMode getLockMode() { return lockMode; } /** * Set the overall {@link LockMode} to be used. The default is * {@link LockMode#NONE} * * @param lockMode The new overall lock mode to use. * * @return this (for method chaining). */ public LockOptions setLockMode(LockMode lockMode) { this.lockMode = lockMode; return this; } /** * Specify the {@link LockMode} to be used for a specific query alias. * * @param alias used to reference the LockMode. * @param lockMode The lock mode to apply to the given alias * @return this LockRequest instance for operation chaining. * * @see Query#setLockMode(String, LockMode) * @see Criteria#setLockMode(LockMode) * @see Criteria#setLockMode(String, LockMode) */ public LockOptions setAliasSpecificLockMode(String alias, LockMode lockMode) { if ( aliasSpecificLockModes == null ) { aliasSpecificLockModes = new LinkedHashMap<>(); } aliasSpecificLockModes.put( alias, lockMode ); return this; } /** * Get the {@link LockMode} explicitly specified for the given alias via * {@link #setAliasSpecificLockMode} *

* Differs from {@link #getEffectiveLockMode} in that here we only return * explicitly specified alias-specific lock modes. * * @param alias The alias for which to locate the explicit lock mode. * * @return The explicit lock mode for that alias. */ public LockMode getAliasSpecificLockMode(String alias) { if ( aliasSpecificLockModes == null ) { return null; } return aliasSpecificLockModes.get( alias ); } /** * Determine the {@link LockMode} to apply to the given alias. If no * mode was explicitly {@link #setAliasSpecificLockMode set}, the * {@link #getLockMode overall mode} is returned. If the overall lock mode is * null as well, {@link LockMode#NONE} is returned. *

* Differs from {@link #getAliasSpecificLockMode} in that here we fallback to we only return * the overall lock mode. * * @param alias The alias for which to locate the effective lock mode. * * @return The effective lock mode. */ public LockMode getEffectiveLockMode(String alias) { LockMode lockMode = getAliasSpecificLockMode( alias ); if ( lockMode == null ) { lockMode = this.lockMode; } return lockMode == null ? LockMode.NONE : lockMode; } /** * Does this LockOptions object define alias-specific lock modes? * * @return {@code true} if this LockOptions object define alias-specific lock modes; {@code false} otherwise. */ public boolean hasAliasSpecificLockModes() { return aliasSpecificLockModes != null && ! aliasSpecificLockModes.isEmpty(); } /** * Get the number of aliases that have specific lock modes defined. * * @return the number of explicitly defined alias lock modes. */ public int getAliasLockCount() { if ( aliasSpecificLockModes == null ) { return 0; } return aliasSpecificLockModes.size(); } /** * Iterator for accessing Alias (key) and LockMode (value) as Map.Entry. * * @return Iterator for accessing the Map.Entry's */ public Iterator> getAliasLockIterator() { return getAliasSpecificLocks().iterator(); } /** * Iterable access to alias (key) and LockMode (value) as Map.Entry. * * @return Iterable for accessing the Map.Entry's */ public Iterable> getAliasSpecificLocks() { if ( aliasSpecificLockModes == null ) { return Collections.emptyList(); } return aliasSpecificLockModes.entrySet(); } /** * Currently needed for follow-on locking. * * @return The greatest of all requested lock modes. */ public LockMode findGreatestLockMode() { LockMode lockModeToUse = getLockMode(); if ( lockModeToUse == null ) { lockModeToUse = LockMode.NONE; } if ( aliasSpecificLockModes == null ) { return lockModeToUse; } for ( LockMode lockMode : aliasSpecificLockModes.values() ) { if ( lockMode.greaterThan( lockModeToUse ) ) { lockModeToUse = lockMode; } } return lockModeToUse; } /** * Retrieve the current timeout setting. *

* The timeout is the amount of time, in milliseconds, we should instruct the database * to wait for any requested pessimistic lock acquisition. *

* {@link #NO_WAIT}, {@link #WAIT_FOREVER} or {@link #SKIP_LOCKED} represent 3 "magic" values. * * @return timeout in milliseconds, {@link #NO_WAIT}, {@link #WAIT_FOREVER} or {@link #SKIP_LOCKED} */ public int getTimeOut() { return timeout; } /** * Set the timeout setting. *

* See {@link #getTimeOut} for a discussion of meaning. * * @param timeout The new timeout setting, in milliseconds * * @return this (for method chaining). * * @see #getTimeOut */ public LockOptions setTimeOut(int timeout) { this.timeout = timeout; return this; } private boolean scope; /** * Retrieve the current lock scope setting. *

* "scope" is a JPA defined term. It is basically a cascading of the lock to associations. * * @return true if locking will be extended to owned associations */ public boolean getScope() { return scope; } /** * Set the scope. * * @param scope The new scope setting * * @return this (for method chaining). */ public LockOptions setScope(boolean scope) { this.scope = scope; return this; } /** * Retrieve the current follow-on-locking setting. * * @return true if follow-on-locking is enabled */ public Boolean getFollowOnLocking() { return followOnLocking; } /** * Set the the follow-on-locking setting. * @param followOnLocking The new follow-on-locking setting * @return this (for method chaining). */ public LockOptions setFollowOnLocking(Boolean followOnLocking) { this.followOnLocking = followOnLocking; return this; } /** * Make a copy. * * @return The copy */ public LockOptions makeCopy() { final LockOptions copy = new LockOptions(); copy( this, copy ); return copy; } /** * Perform a shallow copy. * * @param source Source for the copy (copied from) * @param destination Destination for the copy (copied to) * * @return destination */ public static LockOptions copy(LockOptions source, LockOptions destination) { destination.setLockMode( source.getLockMode() ); destination.setScope( source.getScope() ); destination.setTimeOut( source.getTimeOut() ); if ( source.aliasSpecificLockModes != null ) { destination.aliasSpecificLockModes = new HashMap( source.aliasSpecificLockModes ); } destination.setFollowOnLocking( source.getFollowOnLocking() ); return destination; } public static LockOptions interpret(LockMode lockMode) { if ( lockMode == null || lockMode == LockMode.NONE ) { return NONE; } if ( lockMode == LockMode.READ ) { return READ; } if ( lockMode.greaterThan( LockMode.UPGRADE_NOWAIT ) ) { return UPGRADE; } return new LockOptions( lockMode ); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy