use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class StatefulPersistenceContext method clear.
@Override
public void clear() {
for (Object o : proxiesByKey.values()) {
if (o == null) {
//entry may be GCd
continue;
}
((HibernateProxy) o).getHibernateLazyInitializer().unsetSession();
}
for (Entry<Object, EntityEntry> objectEntityEntryEntry : entityEntryContext.reentrantSafeEntityEntries()) {
// todo : I dont think this need be reentrant safe
if (objectEntityEntryEntry.getKey() instanceof PersistentAttributeInterceptable) {
final PersistentAttributeInterceptor interceptor = ((PersistentAttributeInterceptable) objectEntityEntryEntry.getKey()).$$_hibernate_getInterceptor();
if (interceptor instanceof LazyAttributeLoadingInterceptor) {
((LazyAttributeLoadingInterceptor) interceptor).unsetSession();
}
}
}
for (Map.Entry<PersistentCollection, CollectionEntry> aCollectionEntryArray : IdentityMap.concurrentEntries(collectionEntries)) {
aCollectionEntryArray.getKey().unsetSession(getSession());
}
arrayHolders.clear();
entitiesByKey.clear();
entitiesByUniqueKey.clear();
entityEntryContext.clear();
// entityEntries.clear();
parentsByChild.clear();
entitySnapshotsByKey.clear();
collectionsByKey.clear();
collectionEntries.clear();
if (unownedCollections != null) {
unownedCollections.clear();
}
proxiesByKey.clear();
nullifiableEntityKeys.clear();
if (batchFetchQueue != null) {
batchFetchQueue.clear();
}
// defaultReadOnly is unaffected by clear()
hasNonReadOnlyEntities = false;
if (loadContexts != null) {
loadContexts.cleanup();
}
naturalIdXrefDelegate.clear();
}
use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class StatefulPersistenceContext method getOwnerId.
@Override
public Serializable getOwnerId(String entityName, String propertyName, Object childEntity, Map mergeMap) {
final String collectionRole = entityName + '.' + propertyName;
final EntityPersister persister = session.getFactory().getMetamodel().entityPersister(entityName);
final CollectionPersister collectionPersister = session.getFactory().getMetamodel().collectionPersister(collectionRole);
// try cache lookup first
final Object parent = parentsByChild.get(childEntity);
if (parent != null) {
final EntityEntry entityEntry = entityEntryContext.getEntityEntry(parent);
//there maybe more than one parent, filter by type
if (persister.isSubclassEntityName(entityEntry.getEntityName()) && isFoundInParent(propertyName, childEntity, persister, collectionPersister, parent)) {
return getEntry(parent).getId();
} else {
// remove wrong entry
parentsByChild.remove(childEntity);
}
}
// iterate all the entities currently associated with the persistence context.
for (Entry<Object, EntityEntry> me : reentrantSafeEntityEntries()) {
final EntityEntry entityEntry = me.getValue();
// does this entity entry pertain to the entity persister in which we are interested (owner)?
if (persister.isSubclassEntityName(entityEntry.getEntityName())) {
final Object entityEntryInstance = me.getKey();
//check if the managed object is the parent
boolean found = isFoundInParent(propertyName, childEntity, persister, collectionPersister, entityEntryInstance);
if (!found && mergeMap != null) {
//check if the detached object being merged is the parent
final Object unmergedInstance = mergeMap.get(entityEntryInstance);
final Object unmergedChild = mergeMap.get(childEntity);
if (unmergedInstance != null && unmergedChild != null) {
found = isFoundInParent(propertyName, unmergedChild, persister, collectionPersister, unmergedInstance);
LOG.debugf("Detached object being merged (corresponding with a managed entity) has a collection that [%s] the detached child.", (found ? "contains" : "does not contain"));
}
}
if (found) {
return entityEntry.getId();
}
}
}
// of the loop-in-loop especially considering this is far more likely the 'edge case'
if (mergeMap != null) {
for (Object o : mergeMap.entrySet()) {
final Entry mergeMapEntry = (Entry) o;
if (mergeMapEntry.getKey() instanceof HibernateProxy) {
final HibernateProxy proxy = (HibernateProxy) mergeMapEntry.getKey();
if (persister.isSubclassEntityName(proxy.getHibernateLazyInitializer().getEntityName())) {
boolean found = isFoundInParent(propertyName, childEntity, persister, collectionPersister, mergeMap.get(proxy));
LOG.debugf("Detached proxy being merged has a collection that [%s] the managed child.", (found ? "contains" : "does not contain"));
if (!found) {
found = isFoundInParent(propertyName, mergeMap.get(childEntity), persister, collectionPersister, mergeMap.get(proxy));
LOG.debugf("Detached proxy being merged has a collection that [%s] the detached child being merged..", (found ? "contains" : "does not contain"));
}
if (found) {
return proxy.getHibernateLazyInitializer().getIdentifier();
}
}
}
}
}
return null;
}
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 EntityEntryContext method deserializeEntityEntry.
private static EntityEntry deserializeEntityEntry(char[] entityEntryClassNameArr, ObjectInputStream ois, StatefulPersistenceContext rtn) {
EntityEntry entry = null;
final String entityEntryClassName = new String(entityEntryClassNameArr);
final Class entityEntryClass = rtn.getSession().getFactory().getServiceRegistry().getService(ClassLoaderService.class).classForName(entityEntryClassName);
try {
final Method deserializeMethod = entityEntryClass.getDeclaredMethod("deserialize", ObjectInputStream.class, PersistenceContext.class);
entry = (EntityEntry) deserializeMethod.invoke(null, ois, rtn);
} catch (NoSuchMethodException e) {
log.errorf("Enable to deserialize [%s]", entityEntryClassName);
} catch (InvocationTargetException e) {
log.errorf("Enable to deserialize [%s]", entityEntryClassName);
} catch (IllegalAccessException e) {
log.errorf("Enable to deserialize [%s]", entityEntryClassName);
}
return entry;
}
use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.
the class EntityEntryContext method deserialize.
/**
* JDK serialization hook for deserializing
*
* @param ois The stream to read ourselves from
* @param rtn The persistence context we belong to
*
* @return The deserialized EntityEntryContext
*
* @throws IOException Indicates an IO exception accessing the given stream
* @throws ClassNotFoundException Problem reading stream data
*/
public static EntityEntryContext deserialize(ObjectInputStream ois, StatefulPersistenceContext rtn) throws IOException, ClassNotFoundException {
final int count = ois.readInt();
log.tracef("Starting deserialization of [%s] EntityEntry entries", count);
final EntityEntryContext context = new EntityEntryContext(rtn);
context.count = count;
context.dirty = true;
if (count == 0) {
return context;
}
ManagedEntity previous = null;
for (int i = 0; i < count; i++) {
final boolean isEnhanced = ois.readBoolean();
final Object entity = ois.readObject();
//Call deserialize method dynamically via reflection
final int numChars = ois.readInt();
final char[] entityEntryClassNameArr = new char[numChars];
for (int j = 0; j < numChars; j++) {
entityEntryClassNameArr[j] = ois.readChar();
}
final EntityEntry entry = deserializeEntityEntry(entityEntryClassNameArr, ois, rtn);
final ManagedEntity managedEntity;
if (isEnhanced) {
if (entry.getPersister().isMutable()) {
managedEntity = (ManagedEntity) entity;
} else {
managedEntity = new ImmutableManagedEntityHolder((ManagedEntity) entity);
if (context.immutableManagedEntityXref == null) {
context.immutableManagedEntityXref = new IdentityHashMap<ManagedEntity, ImmutableManagedEntityHolder>();
}
context.immutableManagedEntityXref.put((ManagedEntity) entity, (ImmutableManagedEntityHolder) managedEntity);
}
} else {
managedEntity = new ManagedEntityImpl(entity);
if (context.nonEnhancedEntityXref == null) {
context.nonEnhancedEntityXref = new IdentityHashMap<Object, ManagedEntity>();
}
context.nonEnhancedEntityXref.put(entity, managedEntity);
}
managedEntity.$$_hibernate_setEntityEntry(entry);
if (previous == null) {
context.head = managedEntity;
} else {
previous.$$_hibernate_setNextManagedEntity(managedEntity);
managedEntity.$$_hibernate_setPreviousManagedEntity(previous);
}
previous = managedEntity;
}
context.tail = previous;
return context;
}
Aggregations