use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class StatefulPersistenceContext method reassociateProxy.
/**
* Associate a proxy that was instantiated by another session with this session
*
* @param li The proxy initializer.
* @param proxy The proxy to reassociate.
*/
private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) {
if (li.getSession() != this.getSession()) {
final EntityPersister persister = session.getFactory().getMetamodel().entityPersister(li.getEntityName());
final EntityKey key = session.generateEntityKey(li.getIdentifier(), persister);
// any earlier proxy takes precedence
proxiesByKey.putIfAbsent(key, proxy);
proxy.getHibernateLazyInitializer().setSession(session);
}
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class Collections method processDereferencedCollection.
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 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());
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class AbstractLazyInitializer method setReadOnly.
@Override
public final void setReadOnly(boolean readOnly) {
errorIfReadOnlySettingNotAvailable();
// only update if readOnly is different from current setting
if (this.readOnly != readOnly) {
final EntityPersister persister = session.getFactory().getEntityPersister(entityName);
if (!persister.isMutable() && !readOnly) {
throw new IllegalStateException("cannot make proxies for immutable entities modifiable");
}
this.readOnly = readOnly;
if (initialized) {
EntityKey key = generateEntityKeyOrNull(getIdentifier(), session, getEntityName());
if (key != null && session.getPersistenceContext().containsEntity(key)) {
session.getPersistenceContext().setReadOnly(target, readOnly);
}
}
}
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class AbstractSaveEventListener method performSave.
/**
* Prepares the save call by checking the session caches for a pre-existing
* entity and performing any lifecycle callbacks.
*
* @param entity The entity to be saved.
* @param id The id by which to save the entity.
* @param persister The entity's persister instance.
* @param useIdentityColumn Is an identity column being used?
* @param anything Generally cascade-specific information.
* @param source The session from which the event originated.
* @param requiresImmediateIdAccess does the event context require
* access to the identifier immediately afterQuery execution of this method (if
* not, post-insert style id generators may be postponed if we are outside
* a transaction).
*
* @return The id used to save the entity; may be null depending on the
* type of id generator used and the requiresImmediateIdAccess value
*/
protected Serializable performSave(Object entity, Serializable id, EntityPersister persister, boolean useIdentityColumn, Object anything, EventSource source, boolean requiresImmediateIdAccess) {
if (LOG.isTraceEnabled()) {
LOG.tracev("Saving {0}", MessageHelper.infoString(persister, id, source.getFactory()));
}
final EntityKey key;
if (!useIdentityColumn) {
key = source.generateEntityKey(id, persister);
Object old = source.getPersistenceContext().getEntity(key);
if (old != null) {
if (source.getPersistenceContext().getEntry(old).getStatus() == Status.DELETED) {
source.forceFlush(source.getPersistenceContext().getEntry(old));
} else {
throw new NonUniqueObjectException(id, persister.getEntityName());
}
}
persister.setIdentifier(entity, id, source);
} else {
key = null;
}
if (invokeSaveLifecycle(entity, persister, source)) {
//EARLY EXIT
return id;
}
return performSaveOrReplicate(entity, key, persister, useIdentityColumn, anything, source, requiresImmediateIdAccess);
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class DefaultDeleteEventListener method deleteEntity.
/**
* Perform the entity deletion. Well, as with most operations, does not
* really perform it; just schedules an action/execution with the
* {@link org.hibernate.engine.spi.ActionQueue} for execution during flush.
*
* @param session The originating session
* @param entity The entity to delete
* @param entityEntry The entity's entry in the {@link PersistenceContext}
* @param isCascadeDeleteEnabled Is delete cascading enabled?
* @param persister The entity persister.
* @param transientEntities A cache of already deleted entities.
*/
protected final void deleteEntity(final EventSource session, final Object entity, final EntityEntry entityEntry, final boolean isCascadeDeleteEnabled, final boolean isOrphanRemovalBeforeUpdates, final EntityPersister persister, final Set transientEntities) {
if (LOG.isTraceEnabled()) {
LOG.tracev("Deleting {0}", MessageHelper.infoString(persister, entityEntry.getId(), session.getFactory()));
}
final PersistenceContext persistenceContext = session.getPersistenceContext();
final Type[] propTypes = persister.getPropertyTypes();
final Object version = entityEntry.getVersion();
final Object[] currentState;
if (entityEntry.getLoadedState() == null) {
//ie. the entity came in from update()
currentState = persister.getPropertyValues(entity);
} else {
currentState = entityEntry.getLoadedState();
}
final Object[] deletedState = createDeletedState(persister, currentState, session);
entityEntry.setDeletedState(deletedState);
session.getInterceptor().onDelete(entity, entityEntry.getId(), deletedState, persister.getPropertyNames(), propTypes);
// beforeQuery any callbacks, etc, so subdeletions see that this deletion happened first
persistenceContext.setEntryStatus(entityEntry, Status.DELETED);
final EntityKey key = session.generateEntityKey(entityEntry.getId(), persister);
cascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities);
new ForeignKeys.Nullifier(entity, true, false, session).nullifyTransientReferences(entityEntry.getDeletedState(), propTypes);
new Nullability(session).checkNullability(entityEntry.getDeletedState(), persister, true);
persistenceContext.getNullifiableEntityKeys().add(key);
if (isOrphanRemovalBeforeUpdates) {
// TODO: The removeOrphan concept is a temporary "hack" for HHH-6484. This should be removed once action/task
// ordering is improved.
session.getActionQueue().addAction(new OrphanRemovalAction(entityEntry.getId(), deletedState, version, entity, persister, isCascadeDeleteEnabled, session));
} else {
// Ensures that containing deletions happen beforeQuery sub-deletions
session.getActionQueue().addAction(new EntityDeleteAction(entityEntry.getId(), deletedState, version, entity, persister, isCascadeDeleteEnabled, session));
}
cascadeAfterDelete(session, persister, entity, transientEntities);
// the entry will be removed afterQuery the flush, and will no longer
// override the stale snapshot
// This is now handled by removeEntity() in EntityDeleteAction
//persistenceContext.removeDatabaseSnapshot(key);
}
Aggregations