use of org.hibernate.engine.spi.EntityEntry 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.EntityEntry in project hibernate-orm by hibernate.
the class DefaultLoadEventListener method createProxyIfNecessary.
/**
* 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;
}
use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class DefaultLoadEventListener method loadFromSessionCache.
/**
* Attempts to locate the entity in the session-level cache.
* <p/>
* If allowed to return nulls, then if the entity happens to be found in
* the session cache, we check the entity type for proper handling
* of entity hierarchies.
* <p/>
* If checkDeleted was set to true, then if the entity is found in the
* session-level cache, it's current status within the session cache
* is checked to see if it has previously been scheduled for deletion.
*
* @param event The load event
* @param keyToLoad The EntityKey representing the entity to be loaded.
* @param options The load options.
*
* @return The entity from the session-level cache, or null.
*
* @throws HibernateException Generally indicates problems applying a lock-mode.
*/
protected Object loadFromSessionCache(final LoadEvent event, final EntityKey keyToLoad, final LoadEventListener.LoadType options) throws HibernateException {
SessionImplementor session = event.getSession();
Object old = session.getEntityUsingInterceptor(keyToLoad);
if (old != null) {
// this object was already loaded
EntityEntry oldEntry = session.getPersistenceContext().getEntry(old);
if (options.isCheckDeleted()) {
Status status = oldEntry.getStatus();
if (status == Status.DELETED || status == Status.GONE) {
return REMOVED_ENTITY_MARKER;
}
}
if (options.isAllowNulls()) {
final EntityPersister persister = event.getSession().getFactory().getEntityPersister(keyToLoad.getEntityName());
if (!persister.isInstance(old)) {
return INCONSISTENT_RTN_CLASS_MARKER;
}
}
upgradeLock(old, oldEntry, event.getLockOptions(), event.getSession());
}
return old;
}
use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class AbstractEntityPersister method delete.
/**
* Delete an object
*/
public void delete(Serializable id, Object version, Object object, SharedSessionContractImplementor session) throws HibernateException {
final int span = getTableSpan();
boolean isImpliedOptimisticLocking = !entityMetamodel.isVersioned() && isAllOrDirtyOptLocking();
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, this);
Object entity = session.getPersistenceContext().getEntity(key);
if (entity != null) {
EntityEntry entry = session.getPersistenceContext().getEntry(entity);
loadedState = entry.getLoadedState();
}
}
final String[] deleteStrings;
if (isImpliedOptimisticLocking && loadedState != null) {
// we need to utilize dynamic delete statements
deleteStrings = generateSQLDeletStrings(loadedState);
} else {
// otherwise, utilize the static delete statements
deleteStrings = getSQLDeleteStrings();
}
for (int j = span - 1; j >= 0; j--) {
delete(id, version, j, object, deleteStrings[j], session, loadedState);
}
}
use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class MessageHelper method collectionInfoString.
// collections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Generate an info message string relating to a particular managed
* collection. Attempts to intelligently handle property-refs issues
* where the collection key is not the same as the owner key.
*
* @param persister The persister for the collection
* @param collection The collection itself
* @param collectionKey The collection key
* @param session The session
* @return An info string, in the form [Foo.bars#1]
*/
public static String collectionInfoString(CollectionPersister persister, PersistentCollection collection, Serializable collectionKey, SharedSessionContractImplementor session) {
StringBuilder s = new StringBuilder();
s.append('[');
if (persister == null) {
s.append("<unreferenced>");
} else {
s.append(persister.getRole());
s.append('#');
Type ownerIdentifierType = persister.getOwnerEntityPersister().getIdentifierType();
Serializable ownerKey;
// or is always using the owner id sufficient?
if (collectionKey.getClass().isAssignableFrom(ownerIdentifierType.getReturnedClass())) {
ownerKey = collectionKey;
} else {
Object collectionOwner = collection == null ? null : collection.getOwner();
EntityEntry entry = collectionOwner == null ? null : session.getPersistenceContext().getEntry(collectionOwner);
ownerKey = entry == null ? null : entry.getId();
}
s.append(ownerIdentifierType.toLoggableString(ownerKey, session.getFactory()));
}
s.append(']');
return s.toString();
}
Aggregations