Java Code Examples for org.hibernate.engine.spi.PersistenceContext#getEntry()

The following examples show how to use org.hibernate.engine.spi.PersistenceContext#getEntry() . 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: TwoPhaseLoad.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
/**
 * PostLoad cannot occur during initializeEntity, as that call occurs *before*
 * the Set collections are added to the persistence context by Loader.
 * Without the split, LazyInitializationExceptions can occur in the Entity's
 * postLoad if it acts upon the collection.
 *
 * HHH-6043
 *
 * @param entity The entity
 * @param session The Session
 * @param postLoadEvent The (re-used) post-load event
 */
public static void postLoad(
		final Object entity,
		final SharedSessionContractImplementor session,
		final PostLoadEvent postLoadEvent) {

	if ( session.isEventSource() ) {
		final PersistenceContext persistenceContext
				= session.getPersistenceContext();
		final EntityEntry entityEntry = persistenceContext.getEntry( entity );

		postLoadEvent.setEntity( entity ).setId( entityEntry.getId() ).setPersister( entityEntry.getPersister() );

		final EventListenerGroup<PostLoadEventListener> listenerGroup = session.getFactory()
						.getServiceRegistry()
						.getService( EventListenerRegistry.class )
						.getEventListenerGroup( EventType.POST_LOAD );
		for ( PostLoadEventListener listener : listenerGroup.listeners() ) {
			listener.onPostLoad( postLoadEvent );
		}
	}
}
 
Example 2
Source File: ForumServiceImpl.java    From high-performance-java-persistence with Apache License 2.0 6 votes vote down vote up
@Override
@Transactional(readOnly = true)
public List<Post> findAllByTitle(String title) {
    List<Post> posts = postDAO.findByTitle(title);

    Session session = sessionFactory.getCurrentSession();
    PersistenceContext persistenceContext = ((SharedSessionContractImplementor) session)
            .getPersistenceContext();

    for(Post post : posts) {
        assertTrue(session.contains(post));

        EntityEntry entityEntry = persistenceContext.getEntry(post);
        assertNull(entityEntry.getLoadedState());
    }

    return posts;
}
 
Example 3
Source File: DefaultReactiveLoadEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * If there is already a corresponding proxy associated with the
 * persistence context, return it; otherwise create a proxy, associate it
 * with the persistence context, and return the just-created proxy.
 *
 * @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 persistenceContext The originating session
 *
 * @return The created/existing proxy
 */
private Object createProxyIfNecessary(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final PersistenceContext persistenceContext) {
	Object existing = persistenceContext.getEntity( keyToLoad );
	final boolean traceEnabled = LOG.isTraceEnabled();
	if ( existing != null ) {
		// return existing object or initialized proxy (unless deleted)
		if ( traceEnabled ) {
			LOG.trace( "Entity found in session cache" );
		}
		if ( options.isCheckDeleted() ) {
			EntityEntry entry = persistenceContext.getEntry( existing );
			Status status = entry.getStatus();
			if ( status == Status.DELETED || status == Status.GONE ) {
				return null;
			}
		}
		return existing;
	}
	if ( traceEnabled ) {
		LOG.trace( "Creating new proxy for entity" );
	}
	return createProxy( event, persister, keyToLoad, persistenceContext );
}
 
Example 4
Source File: DefaultLoadEventListener.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * If there is already a corresponding proxy associated with the
 * persistence context, return it; otherwise create a proxy, associate it
 * with the persistence context, and return the just-created proxy.
 *
 * @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 persistenceContext The originating session
 *
 * @return The created/existing proxy
 */
private Object createProxyIfNecessary(
		final LoadEvent event,
		final EntityPersister persister,
		final EntityKey keyToLoad,
		final LoadEventListener.LoadType options,
		final PersistenceContext persistenceContext) {
	Object existing = persistenceContext.getEntity( keyToLoad );
	if ( existing != null ) {
		// return existing object or initialized proxy (unless deleted)
		if ( traceEnabled ) {
			LOG.trace( "Entity found in session cache" );
		}
		if ( options.isCheckDeleted() ) {
			EntityEntry entry = persistenceContext.getEntry( existing );
			Status status = entry.getStatus();
			if ( status == Status.DELETED || status == Status.GONE ) {
				return null;
			}
		}
		return existing;
	}
	if ( traceEnabled ) {
		LOG.trace( "Creating new proxy for entity" );
	}
	// return new uninitialized proxy
	Object proxy = persister.createProxy( event.getEntityId(), event.getSession() );
	persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( keyToLoad );
	persistenceContext.addProxy( keyToLoad, proxy );
	return proxy;
}
 
Example 5
Source File: ForumServiceImpl.java    From high-performance-java-persistence with Apache License 2.0 5 votes vote down vote up
@Override
@Transactional
public Post findById(Long id) {
    Post post = postDAO.findById(id);

    Session session = sessionFactory.getCurrentSession();
    PersistenceContext persistenceContext = ((SharedSessionContractImplementor) session)
        .getPersistenceContext();

    EntityEntry entityEntry = persistenceContext.getEntry(post);
    assertNotNull(entityEntry.getLoadedState());

    return post;
}
 
Example 6
Source File: ReactiveAbstractEntityPersister.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
default CompletionStage<?> deleteReactive(
		Serializable id, Object version, Object object,
		SharedSessionContractImplementor session)
		throws HibernateException {
	final int span = delegate().getTableSpan();
	boolean isImpliedOptimisticLocking = !delegate().getEntityMetamodel().isVersioned() && isAllOrDirtyOptimisticLocking();
	Object[] loadedState = null;
	if ( isImpliedOptimisticLocking ) {
		// need to treat this as if it where optimistic-lock="all" (dirty does *not* make sense);
		// first we need to locate the "loaded" state
		//
		// Note, it potentially could be a proxy, so doAfterTransactionCompletion the location the safe way...
		final EntityKey key = session.generateEntityKey( id, delegate());
		final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
		Object entity = persistenceContext.getEntity( key );
		if ( entity != null ) {
			EntityEntry entry = persistenceContext.getEntry( entity );
			loadedState = entry.getLoadedState();
		}
	}

	final String[] deleteStrings;
	if ( isImpliedOptimisticLocking && loadedState != null ) {
		// we need to utilize dynamic delete statements
		deleteStrings = generateSQLDeleteStrings( loadedState );
	}
	else {
		// otherwise, utilize the static delete statements
		deleteStrings = delegate().getSQLDeleteStrings();
	}

	CompletionStage<?> deleteStage = CompletionStages.nullFuture();
	for ( int j = span - 1; j >= 0; j-- ) {
		// For now we assume there is only one delete query
		int jj = j;
		Object[] state = loadedState;
		deleteStage = deleteStage.thenCompose(
				v-> deleteReactive(
						id,
						version,
						jj,
						object,
						deleteStrings[jj],
						session,
						state
				));
	}

	return deleteStage;
}
 
Example 7
Source File: DefaultReactiveLockEventListener.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public CompletionStage<Void> reactiveOnLock(LockEvent event) throws HibernateException {
	if ( event.getObject() == null ) {
		throw new NullPointerException( "attempted to lock null" );
	}

	if ( event.getLockMode() == LockMode.WRITE ) {
		throw new HibernateException( "Invalid lock mode for lock()" );
	}

	if ( event.getLockMode() == LockMode.UPGRADE_SKIPLOCKED ) {
		log.explicitSkipLockedLockCombo();
	}

	SessionImplementor source = event.getSession();
	final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
	Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
	//TODO: if object was an uninitialized proxy, this is inefficient,
	//      resulting in two SQL selects

	EntityEntry entry = persistenceContext.getEntry(entity);
	CompletionStage<EntityEntry> stage;
	if (entry==null) {
		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
		final Serializable id = persister.getIdentifier( entity, source );
		stage = ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source )
				.thenApply(
						trans -> {
							if (!trans) {
								throw new TransientObjectException(
										"cannot lock an unsaved transient instance: " +
												persister.getEntityName()
								);
							}

							EntityEntry e = reassociate(event, entity, id, persister);
							cascadeOnLock(event, persister, entity);
							return e;
						} );

	}
	else {
		stage = CompletionStages.completedFuture(entry);
	}

	return stage.thenCompose( e -> upgradeLock( entity, e, event.getLockOptions(), event.getSession() ) );
}
 
Example 8
Source File: Collections.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
private static void processDereferencedCollection(PersistentCollection coll, SessionImplementor session) {
	final PersistenceContext persistenceContext = session.getPersistenceContext();
	final CollectionEntry entry = persistenceContext.getCollectionEntry( coll );
	final CollectionPersister loadedPersister = entry.getLoadedPersister();

	if ( loadedPersister != null && LOG.isDebugEnabled() ) {
		LOG.debugf(
				"Collection dereferenced: %s",
				MessageHelper.collectionInfoString( loadedPersister, 
						coll, entry.getLoadedKey(), session
				)
		);
	}

	// do a check
	final boolean hasOrphanDelete = loadedPersister != null && loadedPersister.hasOrphanDelete();
	if ( hasOrphanDelete ) {
		Serializable ownerId = loadedPersister.getOwnerEntityPersister().getIdentifier( coll.getOwner(), session );
		if ( ownerId == null ) {
			// the owning entity may have been deleted and its identifier unset due to
			// identifier-rollback; in which case, try to look up its identifier from
			// the persistence context
			if ( session.getFactory().getSessionFactoryOptions().isIdentifierRollbackEnabled() ) {
				final EntityEntry ownerEntry = persistenceContext.getEntry( coll.getOwner() );
				if ( ownerEntry != null ) {
					ownerId = ownerEntry.getId();
				}
			}
			if ( ownerId == null ) {
				throw new AssertionFailure( "Unable to determine collection owner identifier for orphan-delete processing" );
			}
		}
		final EntityKey key = session.generateEntityKey( ownerId, loadedPersister.getOwnerEntityPersister() );
		final Object owner = persistenceContext.getEntity( key );
		if ( owner == null ) {
			throw new AssertionFailure(
					"collection owner not associated with session: " +
					loadedPersister.getRole()
			);
		}
		final EntityEntry e = persistenceContext.getEntry( owner );
		//only collections belonging to deleted entities are allowed to be dereferenced in the case of orphan delete
		if ( e != null && e.getStatus() != Status.DELETED && e.getStatus() != Status.GONE ) {
			throw new HibernateException(
					"A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: " +
					loadedPersister.getRole()
			);
		}
	}

	// do the work
	entry.setCurrentPersister( null );
	entry.setCurrentKey( null );
	prepareCollectionForUpdate( coll, entry, session.getFactory() );

}
 
Example 9
Source File: DefaultDeleteEventListener.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Handle the given delete event.  This is the cascaded form.
 *
 * @param event The delete event.
 * @param transientEntities The cache of entities already deleted
 *
 * @throws HibernateException
 */
public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {

	final EventSource source = event.getSession();

	final PersistenceContext persistenceContext = source.getPersistenceContext();
	Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );

	EntityEntry entityEntry = persistenceContext.getEntry( entity );
	final EntityPersister persister;
	final Serializable id;
	final Object version;

	if ( entityEntry == null ) {
		LOG.trace( "Entity was not persistent in delete processing" );

		persister = source.getEntityPersister( event.getEntityName(), entity );

		if ( ForeignKeys.isTransient( persister.getEntityName(), entity, null, source ) ) {
			deleteTransientEntity( source, entity, event.isCascadeDeleteEnabled(), persister, transientEntities );
			// EARLY EXIT!!!
			return;
		}
		performDetachedEntityDeletionCheck( event );

		id = persister.getIdentifier( entity, source );

		if ( id == null ) {
			throw new TransientObjectException(
					"the detached instance passed to delete() had a null identifier"
			);
		}

		final EntityKey key = source.generateEntityKey( id, persister );

		persistenceContext.checkUniqueness( key, entity );

		new OnUpdateVisitor( source, id, entity ).process( entity, persister );

		version = persister.getVersion( entity );

		entityEntry = persistenceContext.addEntity(
				entity,
				(persister.isMutable() ? Status.MANAGED : Status.READ_ONLY),
				persister.getPropertyValues( entity ),
				key,
				version,
				LockMode.NONE,
				true,
				persister,
				false
		);
	}
	else {
		LOG.trace( "Deleting a persistent instance" );

		if ( entityEntry.getStatus() == Status.DELETED || entityEntry.getStatus() == Status.GONE ) {
			LOG.trace( "Object was already deleted" );
			return;
		}
		persister = entityEntry.getPersister();
		id = entityEntry.getId();
		version = entityEntry.getVersion();
	}

	/*if ( !persister.isMutable() ) {
		throw new HibernateException(
				"attempted to delete an object of immutable class: " +
				MessageHelper.infoString(persister)
			);
	}*/

	if ( invokeDeleteLifecycle( source, entity, persister ) ) {
		return;
	}

	deleteEntity(
			source,
			entity,
			entityEntry,
			event.isCascadeDeleteEnabled(),
			event.isOrphanRemovalBeforeUpdates(),
			persister,
			transientEntities
	);

	if ( source.getFactory().getSettings().isIdentifierRollbackEnabled() ) {
		persister.resetIdentifier( entity, id, version, source );
	}
}
 
Example 10
Source File: EntityInsertAction.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void execute() throws HibernateException {
	nullifyTransientReferencesIfNotAlready();

	final EntityPersister persister = getPersister();
	final SharedSessionContractImplementor session = getSession();
	final Object instance = getInstance();
	final Serializable id = getId();

	final boolean veto = preInsert();

	// Don't need to lock the cache here, since if someone
	// else inserted the same pk first, the insert would fail

	if ( !veto ) {
		
		persister.insert( id, getState(), instance, session );
		PersistenceContext persistenceContext = session.getPersistenceContext();
		final EntityEntry entry = persistenceContext.getEntry( instance );
		if ( entry == null ) {
			throw new AssertionFailure( "possible non-threadsafe access to session" );
		}
		
		entry.postInsert( getState() );

		if ( persister.hasInsertGeneratedProperties() ) {
			persister.processInsertGeneratedProperties( id, instance, getState(), session );
			if ( persister.isVersionPropertyGenerated() ) {
				version = Versioning.getVersion( getState(), persister );
			}
			entry.postUpdate( instance, getState(), version );
		}

		persistenceContext.registerInsertedKey( persister, getId() );
	}

	final SessionFactoryImplementor factory = session.getFactory();

	if ( isCachePutEnabled( persister, session ) ) {
		final CacheEntry ce = persister.buildCacheEntry(
				instance,
				getState(),
				version,
				session
		);
		cacheEntry = persister.getCacheEntryStructure().structure( ce );
		final EntityDataAccess cache = persister.getCacheAccessStrategy();
		final Object ck = cache.generateCacheKey( id, persister, factory, session.getTenantIdentifier() );

		final boolean put = cacheInsert( persister, ck );

		if ( put && factory.getStatistics().isStatisticsEnabled() ) {
			factory.getStatistics().entityCachePut(
					StatsHelper.INSTANCE.getRootEntityRole( persister ),
					cache.getRegion().getName()
			);
		}
	}

	handleNaturalIdPostSaveNotifications( id );

	postInsert();

	if ( factory.getStatistics().isStatisticsEnabled() && !veto ) {
		factory.getStatistics().insertEntity( getPersister().getEntityName() );
	}

	markExecuted();
}
 
Example 11
Source File: TwoPhaseLoad.java    From lams with GNU General Public License v2.0 3 votes vote down vote up
/**
 * Perform the second step of 2-phase load. Fully initialize the entity
 * instance.
 * <p/>
 * After processing a JDBC result set, we "resolve" all the associations
 * between the entities which were instantiated and had their state
 * "hydrated" into an array
 *
 * @param entity The entity being loaded
 * @param readOnly Is the entity being loaded as read-only
 * @param session The Session
 * @param preLoadEvent The (re-used) pre-load event
 */
public static void initializeEntity(
		final Object entity,
		final boolean readOnly,
		final SharedSessionContractImplementor session,
		final PreLoadEvent preLoadEvent) {
	final PersistenceContext persistenceContext = session.getPersistenceContext();
	final EntityEntry entityEntry = persistenceContext.getEntry( entity );
	if ( entityEntry == null ) {
		throw new AssertionFailure( "possible non-threadsafe access to the session" );
	}
	doInitializeEntity( entity, entityEntry, readOnly, session, preLoadEvent );
}