Java Code Examples for org.hibernate.persister.entity.EntityPersister#canWriteToCache()

The following examples show how to use org.hibernate.persister.entity.EntityPersister#canWriteToCache() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: StatefulPersistenceContext.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void registerInsertedKey(EntityPersister persister, Serializable id) {
	// we only are worried about registering these if the persister defines caching
	if ( persister.canWriteToCache() ) {
		if ( insertedKeysMap == null ) {
			insertedKeysMap = new HashMap<>();
		}
		final String rootEntityName = persister.getRootEntityName();
		List<Serializable> insertedEntityIds = insertedKeysMap.get( rootEntityName );
		if ( insertedEntityIds == null ) {
			insertedEntityIds = new ArrayList<>();
			insertedKeysMap.put( rootEntityName, insertedEntityIds );
		}
		insertedEntityIds.add( id );
	}
}
 
Example 2
Source File: StatefulPersistenceContext.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean wasInsertedDuringTransaction(EntityPersister persister, Serializable id) {
	// again, we only really care if the entity is cached
	if ( persister.canWriteToCache() ) {
		if ( insertedKeysMap != null ) {
			final List<Serializable> insertedEntityIds = insertedKeysMap.get( persister.getRootEntityName() );
			if ( insertedEntityIds != null ) {
				return insertedEntityIds.contains( id );
			}
		}
	}
	return false;
}
 
Example 3
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * If the class to be loaded has been configured with a cache, then lock
 * given id in that cache and then perform the load.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param source The originating session
 *
 * @return The loaded entity
 *
 * @throws HibernateException
 */
private Object lockAndLoad(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final SessionImplementor source) {
	SoftLock lock = null;
	final Object ck;
	final EntityDataAccess cache = persister.getCacheAccessStrategy();
	if ( persister.canWriteToCache() ) {
		ck = cache.generateCacheKey(
				event.getEntityId(),
				persister,
				source.getFactory(),
				source.getTenantIdentifier()
		);
		lock = persister.getCacheAccessStrategy().lockItem( source, ck, null );
	}
	else {
		ck = null;
	}

	Object entity;
	try {
		entity = load( event, persister, keyToLoad, options );
	}
	finally {
		if ( persister.canWriteToCache() ) {
			cache.unlockItem( source, ck, lock );
		}
	}

	return event.getSession().getPersistenceContext().proxyFor( persister, keyToLoad, entity );
}
 
Example 4
Source File: EntityDeleteAction.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) throws HibernateException {
	EntityPersister entityPersister = getPersister();
	if ( entityPersister.canWriteToCache() ) {
		EntityDataAccess cache = entityPersister.getCacheAccessStrategy();
		final Object ck = cache.generateCacheKey(
				getId(),
				entityPersister,
				session.getFactory(),
				session.getTenantIdentifier()
		);
		cache.unlockItem( session, ck, lock );
	}
	postCommitDelete( success );
}
 
Example 5
Source File: BulkOperationCleanupAction.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Constructs an action to cleanup "affected cache regions" based on a
 * set of affected table spaces.  This differs from {@link #BulkOperationCleanupAction(SharedSessionContractImplementor, Queryable[])}
 * in that here we have the affected <strong>table names</strong>.  From those
 * we deduce the entity persisters which are affected based on the defined
 * {@link EntityPersister#getQuerySpaces() table spaces}; and from there, we
 * determine the affected collection regions based on any collections
 * in which those entity persisters participate as elements/keys/etc.
 *
 * @param session The session to which this request is tied.
 * @param tableSpaces The table spaces.
 */
@SuppressWarnings({ "unchecked" })
public BulkOperationCleanupAction(SharedSessionContractImplementor session, Set tableSpaces) {
	final LinkedHashSet<String> spacesList = new LinkedHashSet<>();
	spacesList.addAll( tableSpaces );

	final SessionFactoryImplementor factory = session.getFactory();
	for ( EntityPersister persister : factory.getMetamodel().entityPersisters().values() ) {
		final String[] entitySpaces = (String[]) persister.getQuerySpaces();
		if ( affectedEntity( tableSpaces, entitySpaces ) ) {
			spacesList.addAll( Arrays.asList( entitySpaces ) );

			if ( persister.canWriteToCache() ) {
				entityCleanups.add( new EntityCleanup( persister.getCacheAccessStrategy(), session ) );
			}
			if ( persister.hasNaturalIdentifier() && persister.hasNaturalIdCache() ) {
				naturalIdCleanups.add( new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy(), session ) );
			}

			final Set<String> roles = session.getFactory().getMetamodel().getCollectionRolesByEntityParticipant( persister.getEntityName() );
			if ( roles != null ) {
				for ( String role : roles ) {
					final CollectionPersister collectionPersister = factory.getMetamodel().collectionPersister( role );
					if ( collectionPersister.hasCache() ) {
						collectionCleanups.add(
								new CollectionCleanup( collectionPersister.getCacheAccessStrategy(), session )
						);
					}
				}
			}
		}
	}

	this.affectedTableSpaces = spacesList.toArray( new String[ spacesList.size() ] );
}
 
Example 6
Source File: EntityUpdateAction.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) throws CacheException {
	final EntityPersister persister = getPersister();
	if ( persister.canWriteToCache() ) {
		final EntityDataAccess cache = persister.getCacheAccessStrategy();
		final Object ck = cache.generateCacheKey(
				getId(),
				persister,
				session.getFactory(),
				session.getTenantIdentifier()
				
		);

		if ( success &&
				cacheEntry != null &&
				!persister.isCacheInvalidationRequired() &&
				session.getCacheMode().isPutEnabled() ) {
			final boolean put = cacheAfterUpdate( cache, ck );

			if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
				session.getFactory().getStatistics().entityCachePut(
						StatsHelper.INSTANCE.getRootEntityRole( persister ),
						getPersister().getCacheAccessStrategy().getRegion().getName()
				);
			}
		}
		else {
			cache.unlockItem(session, ck, lock );
		}
	}
	postCommitUpdate( success );
}
 
Example 7
Source File: ReactiveEntityDeleteAction.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public CompletionStage<Void> reactiveExecute() throws HibernateException {
	final Serializable id = getId();
	final EntityPersister persister = getPersister();
	final SharedSessionContractImplementor session = getSession();
	final Object instance = getInstance();

	final boolean veto = preDelete();

	Object version = getVersion();
	if ( persister.isVersionPropertyGenerated() ) {
		// we need to grab the version value from the entity, otherwise
		// we have issues with generated-version entities that may have
		// multiple actions queued during the same flush
		version = persister.getVersion( instance );
	}

	final Object ck;
	if ( persister.canWriteToCache() ) {
		final EntityDataAccess cache = persister.getCacheAccessStrategy();
		ck = cache.generateCacheKey( id, persister, session.getFactory(), session.getTenantIdentifier() );
		setLock( cache.lockItem( session, ck, version ) );
	}
	else {
		ck = null;
	}

	CompletionStage<?> deleteStep = CompletionStages.nullFuture();
	if ( !isCascadeDeleteEnabled() && !veto ) {
		deleteStep = ((ReactiveEntityPersister) persister).deleteReactive( id, version, instance, session );
	}

	return deleteStep.thenAccept( deleteAR -> {
		//postDelete:
		// After actually deleting a row, record the fact that the instance no longer
		// exists on the database (needed for identity-column key generation), and
		// remove it from the session cache
		final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
		final EntityEntry entry = persistenceContext.removeEntry( instance );
		if ( entry == null ) {
			throw new AssertionFailure( "possible non-threadsafe access to session" );
		}
		entry.postDelete();

		persistenceContext.removeEntity( entry.getEntityKey() );
		persistenceContext.removeProxy( entry.getEntityKey() );

		if ( persister.canWriteToCache() ) {
			persister.getCacheAccessStrategy().remove( session, ck );
		}

		persistenceContext.getNaturalIdHelper().removeSharedNaturalIdCrossReference(
				persister,
				id,
				getNaturalIdValues()
		);

		postDelete();

		final StatisticsImplementor statistics = getSession().getFactory().getStatistics();
		if ( statistics.isStatisticsEnabled() && !veto ) {
			statistics.deleteEntity( getPersister().getEntityName() );
		}
	} );
}
 
Example 8
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * If the class to be loaded has been configured with a cache, then lock
 * given id in that cache and then perform the load.
 *
 * @param event The initiating load request event
 * @param persister The persister corresponding to the entity to be loaded
 * @param keyToLoad The key of the entity to be loaded
 * @param options The defined load options
 * @param source The originating session
 *
 * @return The loaded entity
 */
private CompletionStage<Object> lockAndLoad(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final SessionImplementor source) {
	final SoftLock lock;
	final Object ck;
	final EntityDataAccess cache = persister.getCacheAccessStrategy();
	final boolean canWriteToCache = persister.canWriteToCache();
	if ( canWriteToCache ) {
		ck = cache.generateCacheKey(
				event.getEntityId(),
				persister,
				source.getFactory(),
				source.getTenantIdentifier()
		);
		lock = cache.lockItem( source, ck, null );
	}
	else {
		ck = null;
		lock = null;
	}

	try {
		return load( event, persister, keyToLoad, options )
				.whenComplete( (v, x) -> {
					if ( canWriteToCache ) {
						cache.unlockItem( source, ck, lock );
					}
				} )
				.thenApply( entity -> source.getPersistenceContextInternal().proxyFor( persister, keyToLoad, entity ) );
	}
	catch (HibernateException he) {
		//in case load() throws an exception
		if ( canWriteToCache ) {
			cache.unlockItem( source, ck, lock );
		}
		throw he;
	}
}
 
Example 9
Source File: DefaultReactiveLockEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Performs a pessimistic lock upgrade on a given entity, if needed.
 *
 * @param object The entity for which to upgrade the lock.
 * @param entry The entity's EntityEntry instance.
 * @param lockOptions contains the requested lock mode.
 * @param source The session which is the source of the event being processed.
 */
protected CompletionStage<Void> upgradeLock(Object object, EntityEntry entry,
											LockOptions lockOptions,
											EventSource source) {

	LockMode requestedLockMode = lockOptions.getLockMode();
	if ( requestedLockMode.greaterThan( entry.getLockMode() ) ) {
		// The user requested a "greater" (i.e. more restrictive) form of
		// pessimistic lock

		if ( entry.getStatus() != Status.MANAGED ) {
			throw new ObjectDeletedException(
					"attempted to lock a deleted instance",
					entry.getId(),
					entry.getPersister().getEntityName()
			);
		}

		final EntityPersister persister = entry.getPersister();

		if ( log.isTraceEnabled() ) {
			log.tracev(
					"Locking {0} in mode: {1}",
					MessageHelper.infoString( persister, entry.getId(), source.getFactory() ),
					requestedLockMode
			);
		}

		final boolean cachingEnabled = persister.canWriteToCache();
		final SoftLock lock;
		final Object ck;
		if ( cachingEnabled ) {
			EntityDataAccess cache = persister.getCacheAccessStrategy();
			ck = cache.generateCacheKey(
					entry.getId(),
					persister,
					source.getFactory(),
					source.getTenantIdentifier()
			);
			lock = cache.lockItem( source, ck, entry.getVersion() );
		}
		else {
			lock = null;
			ck = null;
		}

		return ((ReactiveEntityPersister) persister).lockReactive(
				entry.getId(),
				entry.getVersion(),
				object,
				lockOptions,
				source
		).thenAccept( v -> entry.setLockMode(requestedLockMode) )
				.whenComplete( (r, e) -> {
					// the database now holds a lock + the object is flushed from the cache,
					// so release the soft lock
					if ( cachingEnabled ) {
						persister.getCacheAccessStrategy().unlockItem( source, ck, lock );
					}
				} );

	}
	else {
		return CompletionStages.nullFuture();
	}
}
 
Example 10
Source File: StatelessSessionImpl.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
	public void refresh(String entityName, Object entity, LockMode lockMode) {
		final EntityPersister persister = this.getEntityPersister( entityName, entity );
		final Serializable id = persister.getIdentifier( entity, this );
		if ( LOG.isTraceEnabled() ) {
			LOG.tracev( "Refreshing transient {0}", MessageHelper.infoString( persister, id, this.getFactory() ) );
		}
		// TODO : can this ever happen???
//		EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
//		if ( source.getPersistenceContext().getEntry( key ) != null ) {
//			throw new PersistentObjectException(
//					"attempted to refresh transient instance when persistent " +
//					"instance was already associated with the Session: " +
//					MessageHelper.infoString( persister, id, source.getFactory() )
//			);
//		}

		if ( persister.canWriteToCache() ) {
			final EntityDataAccess cacheAccess = persister.getCacheAccessStrategy();
			if ( cacheAccess != null ) {
				final Object ck = cacheAccess.generateCacheKey(
						id,
						persister,
						getFactory(),
						getTenantIdentifier()
				);
				cacheAccess.evict( ck );
			}
		}

		String previousFetchProfile = this.getLoadQueryInfluencers().getInternalFetchProfile();
		Object result = null;
		try {
			this.getLoadQueryInfluencers().setInternalFetchProfile( "refresh" );
			result = persister.load( id, entity, getNullSafeLockMode( lockMode ), this );
		}
		finally {
			this.getLoadQueryInfluencers().setInternalFetchProfile( previousFetchProfile );
		}
		UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() );
	}
 
Example 11
Source File: AbstractLockUpgradeEventListener.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Performs a pessimistic lock upgrade on a given entity, if needed.
 *
 * @param object The entity for which to upgrade the lock.
 * @param entry The entity's EntityEntry instance.
 * @param lockOptions contains the requested lock mode.
 * @param source The session which is the source of the event being processed.
 */
protected void upgradeLock(Object object, EntityEntry entry, LockOptions lockOptions, EventSource source) {

	LockMode requestedLockMode = lockOptions.getLockMode();
	if ( requestedLockMode.greaterThan( entry.getLockMode() ) ) {
		// The user requested a "greater" (i.e. more restrictive) form of
		// pessimistic lock

		if ( entry.getStatus() != Status.MANAGED ) {
			throw new ObjectDeletedException(
					"attempted to lock a deleted instance",
					entry.getId(),
					entry.getPersister().getEntityName()
			);
		}

		final EntityPersister persister = entry.getPersister();

		if ( log.isTraceEnabled() ) {
			log.tracev(
					"Locking {0} in mode: {1}",
					MessageHelper.infoString( persister, entry.getId(), source.getFactory() ),
					requestedLockMode
			);
		}

		final boolean cachingEnabled = persister.canWriteToCache();
		SoftLock lock = null;
		Object ck = null;
		try {
			if ( cachingEnabled ) {
				EntityDataAccess cache = persister.getCacheAccessStrategy();
				ck = cache.generateCacheKey( entry.getId(), persister, source.getFactory(), source.getTenantIdentifier() );
				lock = cache.lockItem( source, ck, entry.getVersion() );
			}

			if ( persister.isVersioned() && requestedLockMode == LockMode.FORCE  ) {
				// todo : should we check the current isolation mode explicitly?
				Object nextVersion = persister.forceVersionIncrement(
						entry.getId(), entry.getVersion(), source
				);
				entry.forceLocked( object, nextVersion );
			}
			else {
				persister.lock( entry.getId(), entry.getVersion(), object, lockOptions, source );
			}
			entry.setLockMode(requestedLockMode);
		}
		finally {
			// the database now holds a lock + the object is flushed from the cache,
			// so release the soft lock
			if ( cachingEnabled ) {
				persister.getCacheAccessStrategy().unlockItem( source, ck, lock );
			}
		}

	}
}
 
Example 12
Source File: EntityDeleteAction.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void execute() throws HibernateException {
	final Serializable id = getId();
	final EntityPersister persister = getPersister();
	final SharedSessionContractImplementor session = getSession();
	final Object instance = getInstance();

	final boolean veto = preDelete();

	Object version = this.version;
	if ( persister.isVersionPropertyGenerated() ) {
		// we need to grab the version value from the entity, otherwise
		// we have issues with generated-version entities that may have
		// multiple actions queued during the same flush
		version = persister.getVersion( instance );
	}

	final Object ck;
	if ( persister.canWriteToCache() ) {
		final EntityDataAccess cache = persister.getCacheAccessStrategy();
		ck = cache.generateCacheKey( id, persister, session.getFactory(), session.getTenantIdentifier() );
		lock = cache.lockItem( session, ck, version );
	}
	else {
		ck = null;
	}

	if ( !isCascadeDeleteEnabled && !veto ) {
		persister.delete( id, version, instance, session );
	}
	
	//postDelete:
	// After actually deleting a row, record the fact that the instance no longer 
	// exists on the database (needed for identity-column key generation), and
	// remove it from the session cache
	final PersistenceContext persistenceContext = session.getPersistenceContext();
	final EntityEntry entry = persistenceContext.removeEntry( instance );
	if ( entry == null ) {
		throw new AssertionFailure( "possible nonthreadsafe access to session" );
	}
	entry.postDelete();

	persistenceContext.removeEntity( entry.getEntityKey() );
	persistenceContext.removeProxy( entry.getEntityKey() );
	
	if ( persister.canWriteToCache() ) {
		persister.getCacheAccessStrategy().remove( session, ck);
	}

	persistenceContext.getNaturalIdHelper().removeSharedNaturalIdCrossReference( persister, id, naturalIdValues );

	postDelete();

	if ( getSession().getFactory().getStatistics().isStatisticsEnabled() && !veto ) {
		getSession().getFactory().getStatistics().deleteEntity( getPersister().getEntityName() );
	}
}
 
Example 13
Source File: EntityInsertAction.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
private boolean isCachePutEnabled(EntityPersister persister, SharedSessionContractImplementor session) {
	return persister.canWriteToCache()
			&& !persister.isCacheInvalidationRequired()
			&& session.getCacheMode().isPutEnabled();
}