@Override public Object get(final String entityName, final Serializable id, final LockMode lockMode) throws DataAccessException { return executeWithNativeSession(new HibernateCallback<Object>() { @Override public Object doInHibernate(Session session) throws HibernateException { if (lockMode != null) { return session.get(entityName, id, new LockOptions(lockMode)); } else { return session.get(entityName, id); } } }); }
@Override public <T> T load(final Class<T> entityClass, final Serializable id, final LockMode lockMode) throws DataAccessException { return executeWithNativeSession(new HibernateCallback<T>() { @Override @SuppressWarnings("unchecked") public T doInHibernate(Session session) throws HibernateException { if (lockMode != null) { return (T) session.load(entityClass, id, new LockOptions(lockMode)); } else { return (T) session.load(entityClass, id); } } }); }
@Override public Object load(final String entityName, final Serializable id, final LockMode lockMode) throws DataAccessException { return executeWithNativeSession(new HibernateCallback<Object>() { @Override public Object doInHibernate(Session session) throws HibernateException { if (lockMode != null) { return session.load(entityName, id, new LockOptions(lockMode)); } else { return session.load(entityName, id); } } }); }
@Override public void delete(final String entityName, final Object entity, final LockMode lockMode) throws DataAccessException { executeWithNativeSession(new HibernateCallback<Object>() { @Override public Object doInHibernate(Session session) throws HibernateException { checkWriteOperationAllowed(session); if (lockMode != null) { session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity); } session.delete(entityName, entity); return null; } }); }
protected Object doBatchLoad( Serializable id, Loader loaderToUse, SessionImplementor session, Serializable[] ids, Object optionalObject, LockOptions lockOptions) { if ( log.isDebugEnabled() ) { log.debugf( "Batch loading entity: %s", MessageHelper.infoString( persister, ids, session.getFactory() ) ); } QueryParameters qp = buildQueryParameters( id, ids, optionalObject, lockOptions ); try { final List results = loaderToUse.doQueryAndInitializeNonLazyCollections( session, qp, false ); log.debug( "Done entity batch load" ); return getObjectFromList(results, id, session); } catch ( SQLException sqle ) { throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not load an entity batch: " + MessageHelper.infoString( persister(), ids, session.getFactory() ), loaderToUse.getSQLString() ); } }
public EntityLoader( OuterJoinLoadable persister, int batchSize, LockOptions lockOptions, SessionFactoryImplementor factory, LoadQueryInfluencers loadQueryInfluencers) throws MappingException { this( persister, persister.getIdentifierColumnNames(), persister.getIdentifierType(), batchSize, lockOptions, factory, loadQueryInfluencers ); }
protected String generateLockString(int lockTimeout) { final SessionFactoryImplementor factory = getLockable().getFactory(); final LockOptions lockOptions = new LockOptions( getLockMode() ); lockOptions.setTimeOut( lockTimeout ); final SimpleSelect select = new SimpleSelect( factory.getDialect() ) .setLockOptions( lockOptions ) .setTableName( getLockable().getRootTableName() ) .addColumn( getLockable().getRootTableIdentifierColumnNames()[0] ) .addCondition( getLockable().getRootTableIdentifierColumnNames(), "=?" ); if ( getLockable().isVersioned() ) { select.addCondition( getLockable().getVersionColumnName(), "=?" ); } if ( factory.getSettings().isCommentsEnabled() ) { select.setComment( getLockMode() + " lock " + getLockable().getEntityName() ); } return select.toStatementString(); }
@Override public Object load( Serializable id, Object optionalObject, SessionImplementor session, LockOptions lockOptions) { final Serializable[] batch = session.getPersistenceContext() .getBatchFetchQueue() .getEntityBatch( persister(), id, maxBatchSize, persister().getEntityMode() ); final int numberOfIds = ArrayHelper.countNonNull( batch ); if ( numberOfIds <= 1 ) { return singleKeyLoader.load( id, optionalObject, session ); } final Serializable[] idsToLoad = new Serializable[numberOfIds]; System.arraycopy( batch, 0, idsToLoad, 0, numberOfIds ); if ( log.isDebugEnabled() ) { log.debugf( "Batch loading entity: %s", MessageHelper.infoString( persister(), idsToLoad, session.getFactory() ) ); } QueryParameters qp = buildQueryParameters( id, idsToLoad, optionalObject, lockOptions ); List results = dynamicLoader.doEntityBatchFetch( session, qp, idsToLoad ); return getObjectFromList( results, id, session ); }
@Override public void cascade( EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled) { LOG.tracev( "Cascading to lock: {0}", entityName ); LockMode lockMode = LockMode.NONE; LockOptions lr = new LockOptions(); if ( anything instanceof LockOptions ) { LockOptions lockOptions = (LockOptions) anything; lr.setTimeOut( lockOptions.getTimeOut() ); lr.setScope( lockOptions.getScope() ); if ( lockOptions.getScope() ) { lockMode = lockOptions.getLockMode(); } } lr.setLockMode( lockMode ); session.buildLockRequest( lr ).lock( entityName, child ); }
protected QueryParameters buildQueryParameters( Serializable id, Serializable[] ids, Object optionalObject, LockOptions lockOptions) { Type[] types = new Type[ids.length]; Arrays.fill( types, persister().getIdentifierType() ); QueryParameters qp = new QueryParameters(); qp.setPositionalParameterTypes( types ); qp.setPositionalParameterValues( ids ); qp.setOptionalObject( optionalObject ); qp.setOptionalEntityName( persister().getEntityName() ); qp.setOptionalId( id ); qp.setLockOptions( lockOptions ); return qp; }
/** * Get the <tt>FOR UPDATE OF column_list</tt> fragment appropriate for this * dialect given the aliases of the columns to be write locked. * * @param aliases The columns to be write locked. * @param lockOptions the lock options to apply * @return The appropriate <tt>FOR UPDATE OF column_list</tt> clause string. */ @SuppressWarnings({"unchecked", "UnusedParameters"}) public String getForUpdateString(String aliases, LockOptions lockOptions) { LockMode lockMode = lockOptions.getLockMode(); final Iterator<Map.Entry<String, LockMode>> itr = lockOptions.getAliasLockIterator(); while ( itr.hasNext() ) { // seek the highest lock mode final Map.Entry<String, LockMode>entry = itr.next(); final LockMode lm = entry.getValue(); if ( lm.greaterThan( lockMode ) ) { lockMode = lm; } } lockOptions.setLockMode( lockMode ); return getForUpdateString( lockOptions ); }
@Override public String getForUpdateString(final String aliases, final LockOptions lockOptions) { LockMode lockMode = lockOptions.getLockMode(); final Iterator<Map.Entry<String, LockMode>> itr = lockOptions.getAliasLockIterator(); while ( itr.hasNext() ) { // seek the highest lock mode final Map.Entry<String, LockMode> entry = itr.next(); final LockMode lm = entry.getValue(); if ( lm.greaterThan( lockMode ) ) { lockMode = lm; } } // not sure why this is sometimes empty if ( aliases == null || "".equals( aliases ) ) { return getForUpdateString( lockMode ); } return getForUpdateString( lockMode ) + " of " + aliases; }
@Override public String appendLockHint(LockOptions lockOptions, String tableName) { // NOTE : since SQLServer2005 the nowait hint is supported if ( lockOptions.getLockMode() == LockMode.UPGRADE_NOWAIT ) { return tableName + " with (updlock, rowlock, nowait)"; } final LockMode mode = lockOptions.getLockMode(); final boolean isNoWait = lockOptions.getTimeOut() == LockOptions.NO_WAIT; final String noWaitStr = isNoWait ? ", nowait" : ""; switch ( mode ) { case UPGRADE_NOWAIT: return tableName + " with (updlock, rowlock, nowait)"; case UPGRADE: case PESSIMISTIC_WRITE: case WRITE: return tableName + " with (updlock, rowlock" + noWaitStr + " )"; case PESSIMISTIC_READ: return tableName + " with (holdlock, rowlock" + noWaitStr + " )"; default: return tableName; } }
@Override public String appendLockHint(LockOptions lockOptions, String tableName) { final LockMode mode = lockOptions.getLockMode(); switch ( mode ) { case UPGRADE: case UPGRADE_NOWAIT: case PESSIMISTIC_WRITE: case WRITE: return tableName + " with (updlock, rowlock)"; case PESSIMISTIC_READ: return tableName + " with (holdlock, rowlock)"; case UPGRADE_SKIPLOCKED: return tableName + " with (updlock, rowlock, readpast)"; default: return tableName; } }
public CollectionLoader byKey() { final QueryBuildingParameters buildingParameters = new QueryBuildingParameters() { @Override public LoadQueryInfluencers getQueryInfluencers() { return influencers; } @Override public int getBatchSize() { return batchSize; } @Override public LockMode getLockMode() { return LockMode.NONE; } @Override public LockOptions getLockOptions() { return null; } }; return new CollectionLoader( collectionPersister, buildingParameters ) ; }
@Override public void lock(final String entityName, final Object entity, final LockMode lockMode) throws DataAccessException { executeWithNativeSession(new HibernateCallback<Object>() { @Override public Object doInHibernate(Session session) throws HibernateException { session.buildLockRequest(new LockOptions(lockMode)).lock(entityName, entity); return null; } }); }
@Override public void update(final Object entity, final LockMode lockMode) throws DataAccessException { executeWithNativeSession(new HibernateCallback<Object>() { @Override public Object doInHibernate(Session session) throws HibernateException { checkWriteOperationAllowed(session); session.update(entity); if (lockMode != null) { session.buildLockRequest(new LockOptions(lockMode)).lock(entity); } return null; } }); }
private LoadEvent( Serializable entityId, String entityClassName, Object instanceToLoad, LockOptions lockOptions, boolean isAssociationFetch, EventSource source) { super(source); if ( entityId == null ) { throw new IllegalArgumentException("id to load is required for loading"); } if ( lockOptions.getLockMode() == LockMode.WRITE ) { throw new IllegalArgumentException("Invalid lock mode for loading"); } else if ( lockOptions.getLockMode() == null ) { lockOptions.setLockMode(DEFAULT_LOCK_MODE); } this.entityId = entityId; this.entityClassName = entityClassName; this.instanceToLoad = instanceToLoad; this.lockOptions = lockOptions; this.isAssociationFetch = isAssociationFetch; }
/** * Builds a batch-fetch capable loader based on the given persister, lock-options, etc. * * @param persister The entity persister * @param batchSize The maximum number of ids to batch-fetch at once * @param lockOptions The lock options * @param factory The SessionFactory * @param influencers Any influencers that should affect the built query * * @return The loader. */ public UniqueEntityLoader buildLoader( OuterJoinLoadable persister, int batchSize, LockOptions lockOptions, SessionFactoryImplementor factory, LoadQueryInfluencers influencers) { if ( batchSize <= 1 ) { // no batching return buildNonBatchingLoader( persister, lockOptions, factory, influencers ); } return buildBatchingLoader( persister, batchSize, lockOptions, factory, influencers ); }
@Override public String getWriteLockString(int timeout) { if ( timeout == LockOptions.SKIP_LOCKED ) { return getForUpdateSkipLockedString(); } else { return super.getWriteLockString( timeout ); } }
public DynamicEntityLoader( OuterJoinLoadable persister, int maxBatchSize, LockOptions lockOptions, SessionFactoryImplementor factory, LoadQueryInfluencers loadQueryInfluencers) { this( persister, maxBatchSize, lockOptions.getLockMode(), factory, loadQueryInfluencers ); }
@Override public String getReadLockString(int timeout) { if ( timeout == LockOptions.NO_WAIT ) { return " for share nowait"; } else { return " for share"; } }
@Override public Object load(Serializable id, Object optionalObject, SessionImplementor session, LockOptions lockOptions) { final Serializable[] batch = session.getPersistenceContext() .getBatchFetchQueue() .getEntityBatch( persister(), id, batchSizes[0], persister().getEntityMode() ); for ( int i = 0; i < batchSizes.length-1; i++) { final int smallBatchSize = batchSizes[i]; if ( batch[smallBatchSize-1] != null ) { Serializable[] smallBatch = new Serializable[smallBatchSize]; System.arraycopy(batch, 0, smallBatch, 0, smallBatchSize); // for now... final List results = loaders[i].loadEntityBatch( session, smallBatch, persister().getIdentifierType(), optionalObject, persister().getEntityName(), id, persister(), lockOptions ); return getObjectFromList(results, id, session); //EARLY EXIT } } return ( (UniqueEntityLoader) loaders[batchSizes.length-1] ).load(id, optionalObject, session); }
public PaddedBatchingEntityLoader( OuterJoinLoadable persister, int maxBatchSize, LockOptions lockOptions, SessionFactoryImplementor factory, LoadQueryInfluencers loadQueryInfluencers) { super( persister ); this.batchSizes = ArrayHelper.getBatchSizes( maxBatchSize ); this.loaders = new Loader[ batchSizes.length ]; for ( int i = 0; i < batchSizes.length; i++ ) { this.loaders[i] = new EntityLoader( persister, batchSizes[i], lockOptions, factory, loadQueryInfluencers); } validate( maxBatchSize ); }
@Override public Object load(Serializable id, Object optionalObject, SessionImplementor session, LockOptions lockOptions) { final Object result; try { final QueryParameters qp = new QueryParameters(); qp.setPositionalParameterTypes( new Type[] { entityPersister.getIdentifierType() } ); qp.setPositionalParameterValues( new Object[] { id } ); qp.setOptionalObject( optionalObject ); qp.setOptionalEntityName( entityPersister.getEntityName() ); qp.setOptionalId( id ); qp.setLockOptions( lockOptions ); final List results = executeLoad( session, qp, staticLoadQuery, false, null ); result = extractEntityResult( results ); } catch ( SQLException sqle ) { throw getFactory().getSQLExceptionHelper().convert( sqle, "could not load an entity: " + MessageHelper.infoString( entityPersister, id, entityPersister.getIdentifierType(), getFactory() ), staticLoadQuery.getSqlStatement() ); } log.debugf( "Done entity load : %s#%s", getEntityName(), id ); return result; }
@Override public Object load(Serializable id, Object optionalObject, SessionImplementor session, LockOptions lockOptions) { final Serializable[] batch = session.getPersistenceContext() .getBatchFetchQueue() .getEntityBatch( persister(), id, batchSizes[0], persister().getEntityMode() ); for ( int i = 0; i < batchSizes.length-1; i++) { final int smallBatchSize = batchSizes[i]; if ( batch[smallBatchSize-1] != null ) { Serializable[] smallBatch = new Serializable[smallBatchSize]; System.arraycopy(batch, 0, smallBatch, 0, smallBatchSize); // for now... final List results = loaders[i].loadEntityBatch( session, smallBatch, persister().getIdentifierType(), optionalObject, persister().getEntityName(), id, persister(), lockOptions ); //EARLY EXIT return getObjectFromList( results, id, session ); } } return ( loaders[batchSizes.length-1] ).load( id, optionalObject, session, lockOptions ); }
protected final void initProjection( final String projectionString, final String whereString, final String orderByString, final String groupByString, final LockOptions lockOptions) throws MappingException { walkEntityTree( persister, getAlias() ); persisters = new Loadable[0]; initStatementString(projectionString, whereString, orderByString, groupByString, lockOptions); }
protected String determineSql(int timeout) { if ( timeout == LockOptions.WAIT_FOREVER) { return waitForeverSql; } else if ( timeout == LockOptions.NO_WAIT) { return getNoWaitSql(); } else if ( timeout == LockOptions.SKIP_LOCKED) { return getSkipLockedSql(); } else { return generateLockString( timeout ); } }
public CriteriaJoinWalker( final OuterJoinLoadable persister, final CriteriaQueryTranslator translator, final SessionFactoryImplementor factory, final CriteriaImpl criteria, final String rootEntityName, final LoadQueryInfluencers loadQueryInfluencers, final String alias) { super( persister, factory, loadQueryInfluencers, alias ); this.translator = translator; querySpaces = translator.getQuerySpaces(); if ( translator.hasProjection() ) { initProjection( translator.getSelect(), translator.getWhereCondition(), translator.getOrderBy(), translator.getGroupBy(), LockOptions.NONE ); resultTypes = translator.getProjectedTypes(); userAliases = translator.getProjectedAliases(); includeInResultRow = new boolean[ resultTypes.length ]; Arrays.fill( includeInResultRow, true ); } else { initAll( translator.getWhereCondition(), translator.getOrderBy(), LockOptions.NONE ); // root entity comes last userAliasList.add( criteria.getAlias() ); //root entity comes *last* resultTypeList.add( translator.getResultType( criteria ) ); includeInResultRowList.add( true ); userAliases = ArrayHelper.toStringArray( userAliasList ); resultTypes = ArrayHelper.toTypeArray( resultTypeList ); includeInResultRow = ArrayHelper.toBooleanArray( includeInResultRowList ); } }
@Override protected LockMode determineFollowOnLockMode(LockOptions lockOptions) { final LockMode lockModeToUse = lockOptions.findGreatestLockMode(); if ( lockOptions.getAliasLockCount() > 1 ) { // > 1 here because criteria always uses alias map for the root lock mode (under 'this_') LOG.aliasSpecificLockingWithFollowOnLocking( lockModeToUse ); } return lockModeToUse; }
@Override protected LockMode[] getLockModes(LockOptions lockOptions) { final String[] entityAliases = getAliases(); if ( entityAliases == null ) { return null; } final int size = entityAliases.length; LockMode[] lockModesArray = new LockMode[size]; for ( int i=0; i<size; i++ ) { LockMode lockMode = lockOptions.getAliasSpecificLockMode( entityAliases[i] ); lockModesArray[i] = lockMode==null ? lockOptions.getLockMode() : lockMode; } return lockModesArray; }
@Override protected String applyLocks( String sql, QueryParameters parameters, Dialect dialect, List<AfterLoadAction> afterLoadActions) throws QueryException { final LockOptions lockOptions = parameters.getLockOptions(); if ( lockOptions == null || ( lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0 ) ) { return sql; } // user is request locking, lets see if we can apply locking directly to the SQL... // some dialects wont allow locking with paging... afterLoadActions.add( new AfterLoadAction() { private final LockOptions originalLockOptions = lockOptions.makeCopy(); @Override public void afterLoad(SessionImplementor session, Object entity, Loadable persister) { ( (Session) session ).buildLockRequest( originalLockOptions ).lock( persister.getEntityName(), entity ); } } ); parameters.getLockOptions().setLockMode( LockMode.READ ); return sql; }
protected LockMode determineFollowOnLockMode(LockOptions lockOptions) { final LockMode lockModeToUse = lockOptions.findGreatestLockMode(); if ( lockOptions.hasAliasSpecificLockModes() ) { LOG.aliasSpecificLockingWithFollowOnLocking( lockModeToUse ); } return lockModeToUse; }
/** * @param lockOptions a collection of lock modes specified dynamically via the Query interface */ @Override protected LockMode[] getLockModes(LockOptions lockOptions) { if ( lockOptions == null ) { return defaultLockModes; } if ( lockOptions.getAliasLockCount() == 0 && ( lockOptions.getLockMode() == null || LockMode.NONE.equals( lockOptions.getLockMode() ) ) ) { return defaultLockModes; } // unfortunately this stuff can't be cached because // it is per-invocation, not constant for the // QueryTranslator instance LockMode[] lockModesArray = new LockMode[entityAliases.length]; for ( int i = 0; i < entityAliases.length; i++ ) { LockMode lockMode = lockOptions.getEffectiveLockMode( entityAliases[i] ); if ( lockMode == null ) { //NONE, because its the requested lock mode, not the actual! lockMode = LockMode.NONE; } lockModesArray[i] = lockMode; } return lockModesArray; }
private void addKeyManyToOnesToSession(ResultSetProcessingContextImpl context, ComponentType componentType, Object component ) { for ( int i = 0 ; i < componentType.getSubtypes().length ; i++ ) { final Type subType = componentType.getSubtypes()[ i ]; final Object subValue = componentType.getPropertyValue( component, i, context.getSession() ); if ( subType.isEntityType() ) { ( (Session) context.getSession() ).buildLockRequest( LockOptions.NONE ).lock( subValue ); } else if ( subType.isComponentType() ) { addKeyManyToOnesToSession( context, (ComponentType) subType, subValue ); } } }
public void lock( Serializable id, Object version, Object object, LockOptions lockOptions, SessionImplementor session) throws HibernateException { getLocker( lockOptions.getLockMode() ).lock( id, version, object, lockOptions.getTimeOut(), session ); }
protected UniqueEntityLoader createEntityLoader( LockOptions lockOptions, LoadQueryInfluencers loadQueryInfluencers) throws MappingException { //TODO: disable batch loading if lockMode > READ? return BatchingEntityLoaderBuilder.getBuilder( getFactory() ) .buildLoader( this, batchSize, lockOptions, getFactory(), loadQueryInfluencers ); }
private UniqueEntityLoader getAppropriateLoader(LockOptions lockOptions, SessionImplementor session) { if ( queryLoader != null ) { // if the user specified a custom query loader we need to that // regardless of any other consideration return queryLoader; } else if ( isAffectedByEnabledFilters( session ) ) { // because filters affect the rows returned (because they add // restrictions) these need to be next in precedence return createEntityLoader(lockOptions, session.getLoadQueryInfluencers() ); } else if ( session.getLoadQueryInfluencers().getInternalFetchProfile() != null && LockMode.UPGRADE.greaterThan( lockOptions.getLockMode() ) ) { // Next, we consider whether an 'internal' fetch profile has been set. // This indicates a special fetch profile Hibernate needs applied // (for its merge loading process e.g.). return ( UniqueEntityLoader ) getLoaders().get( session.getLoadQueryInfluencers().getInternalFetchProfile() ); } else if ( isAffectedByEnabledFetchProfiles( session ) ) { // If the session has associated influencers we need to adjust the // SQL query used for loading based on those influencers return createEntityLoader(lockOptions, session.getLoadQueryInfluencers() ); } else if ( isAffectedByEntityGraph( session ) ) { return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() ); } else if ( lockOptions.getTimeOut() != LockOptions.WAIT_FOREVER ) { return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() ); } else { return ( UniqueEntityLoader ) getLoaders().get( lockOptions.getLockMode() ); } }