Search in sources :

Example 66 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.

the class Cascade method cascadeProperty.

/**
	 * Cascade an action to the child or children
	 */
private static void cascadeProperty(final CascadingAction action, final CascadePoint cascadePoint, final EventSource eventSource, final int componentPathStackDepth, final Object parent, final Object child, final Type type, final CascadeStyle style, final String propertyName, final Object anything, final boolean isCascadeDeleteEnabled) throws HibernateException {
    if (child != null) {
        if (type.isAssociationType()) {
            final AssociationType associationType = (AssociationType) type;
            if (cascadeAssociationNow(cascadePoint, associationType)) {
                cascadeAssociation(action, cascadePoint, eventSource, componentPathStackDepth, parent, child, type, style, anything, isCascadeDeleteEnabled);
            }
        } else if (type.isComponentType()) {
            cascadeComponent(action, cascadePoint, eventSource, componentPathStackDepth, parent, child, (CompositeType) type, anything);
        }
    }
    // potentially we need to handle orphan deletes for one-to-ones here...
    if (isLogicalOneToOne(type)) {
        // orphan checking
        if (style.hasOrphanDelete() && action.deleteOrphans()) {
            // value is orphaned if loaded state for this property shows not null
            // because it is currently null.
            final EntityEntry entry = eventSource.getPersistenceContext().getEntry(parent);
            if (entry != null && entry.getStatus() != Status.SAVING) {
                final Object loadedValue;
                if (componentPathStackDepth == 0) {
                    // association defined on entity
                    loadedValue = entry.getLoadedValue(propertyName);
                } else {
                    // association defined on component
                    // 		todo : this is currently unsupported because of the fact that
                    //		we do not know the loaded state of this value properly
                    //		and doing so would be very difficult given how components and
                    //		entities are loaded (and how 'loaded state' is put into the
                    //		EntityEntry).  Solutions here are to either:
                    //			1) properly account for components as a 2-phase load construct
                    //			2) just assume the association was just now orphaned and
                    // 				issue the orphan delete.  This would require a special
                    //				set of SQL statements though since we do not know the
                    //				orphaned value, something a delete with a subquery to
                    // 				match the owner.
                    //							final EntityType entityType = (EntityType) type;
                    //							final String getPropertyPath = composePropertyPath( entityType.getPropertyName() );
                    loadedValue = null;
                }
                // entity is managed (without first nulling and manually flushing).
                if (child == null || (loadedValue != null && child != loadedValue)) {
                    final EntityEntry valueEntry = eventSource.getPersistenceContext().getEntry(loadedValue);
                    // already been flushed.  See HHH-7829.
                    if (valueEntry != null) {
                        final String entityName = valueEntry.getPersister().getEntityName();
                        if (LOG.isTraceEnabled()) {
                            final Serializable id = valueEntry.getPersister().getIdentifier(loadedValue, eventSource);
                            final String description = MessageHelper.infoString(entityName, id);
                            LOG.tracev("Deleting orphaned entity instance: {0}", description);
                        }
                        if (type.isAssociationType() && ((AssociationType) type).getForeignKeyDirection().equals(ForeignKeyDirection.TO_PARENT)) {
                            // If FK direction is to-parent, we must remove the orphan *beforeQuery* the queued update(s)
                            // occur.  Otherwise, replacing the association on a managed entity, without manually
                            // nulling and flushing, causes FK constraint violations.
                            eventSource.removeOrphanBeforeUpdates(entityName, loadedValue);
                        } else {
                            // Else, we must delete afterQuery the updates.
                            eventSource.delete(entityName, loadedValue, isCascadeDeleteEnabled, new HashSet());
                        }
                    }
                }
            }
        }
    }
}
Also used : EntityEntry(org.hibernate.engine.spi.EntityEntry) Serializable(java.io.Serializable) AssociationType(org.hibernate.type.AssociationType) CompositeType(org.hibernate.type.CompositeType) HashSet(java.util.HashSet)

Example 67 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.

the class TwoPhaseLoad method initializeEntity.

/**
	 * 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);
}
Also used : EntityEntry(org.hibernate.engine.spi.EntityEntry) AssertionFailure(org.hibernate.AssertionFailure) PersistenceContext(org.hibernate.engine.spi.PersistenceContext)

Example 68 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.

the class SessionImpl method getEntityName.

@Override
public String getEntityName(Object object) {
    checkOpen();
    //		checkTransactionSynchStatus();
    if (object instanceof HibernateProxy) {
        if (!persistenceContext.containsProxy(object)) {
            throw new TransientObjectException("proxy was not associated with the session");
        }
        object = ((HibernateProxy) object).getHibernateLazyInitializer().getImplementation();
    }
    EntityEntry entry = persistenceContext.getEntry(object);
    if (entry == null) {
        throwTransientObjectException(object);
    }
    return entry.getPersister().getEntityName();
}
Also used : TransientObjectException(org.hibernate.TransientObjectException) EntityEntry(org.hibernate.engine.spi.EntityEntry) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Example 69 with EntityEntry

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();
}
Also used : Type(org.hibernate.type.Type) Serializable(java.io.Serializable) EntityEntry(org.hibernate.engine.spi.EntityEntry)

Example 70 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project hibernate-orm by hibernate.

the class UnversionedNoCascadeDereferencedCollectionTest method testMergeNullCollection.

@Test
@TestForIssue(jiraKey = "HHH-9777")
public void testMergeNullCollection() {
    Session s = openSession();
    s.getTransaction().begin();
    UnversionedNoCascadeOne one = new UnversionedNoCascadeOne();
    assertNull(one.getManies());
    s.save(one);
    assertNull(one.getManies());
    EntityEntry eeOne = getEntityEntry(s, one);
    assertNull(eeOne.getLoadedValue("manies"));
    s.flush();
    assertNull(one.getManies());
    assertNull(eeOne.getLoadedValue("manies"));
    s.getTransaction().commit();
    s.close();
    final String role = UnversionedNoCascadeOne.class.getName() + ".manies";
    s = openSession();
    s.getTransaction().begin();
    one = (UnversionedNoCascadeOne) s.merge(one);
    // afterQuery merging, one.getManies() should still be null;
    // the EntityEntry loaded state should contain a PersistentCollection though.
    assertNull(one.getManies());
    eeOne = getEntityEntry(s, one);
    AbstractPersistentCollection maniesEEOneStateOrig = (AbstractPersistentCollection) eeOne.getLoadedValue("manies");
    assertNotNull(maniesEEOneStateOrig);
    // Ensure maniesEEOneStateOrig has role, key, and session properly defined (even though one.manies == null)
    assertEquals(role, maniesEEOneStateOrig.getRole());
    assertEquals(one.getId(), maniesEEOneStateOrig.getKey());
    assertSame(s, maniesEEOneStateOrig.getSession());
    // Ensure there is a CollectionEntry for maniesEEOneStateOrig and that the role, persister, and key are set properly.
    CollectionEntry ceManiesOrig = getCollectionEntry(s, maniesEEOneStateOrig);
    assertNotNull(ceManiesOrig);
    assertEquals(role, ceManiesOrig.getRole());
    assertSame(sessionFactory().getCollectionPersister(role), ceManiesOrig.getLoadedPersister());
    assertEquals(one.getId(), ceManiesOrig.getKey());
    s.flush();
    // Ensure the same EntityEntry is being used.
    assertSame(eeOne, getEntityEntry(s, one));
    // Ensure one.getManies() is still null.
    assertNull(one.getManies());
    // Ensure CollectionEntry for maniesEEOneStateOrig is no longer in the PersistenceContext.
    assertNull(getCollectionEntry(s, maniesEEOneStateOrig));
    // Ensure the original CollectionEntry has role, persister, and key set to null.
    assertNull(ceManiesOrig.getRole());
    assertNull(ceManiesOrig.getLoadedPersister());
    assertNull(ceManiesOrig.getKey());
    // Ensure the PersistentCollection (that was previously returned by eeOne.getLoadedState())
    // has key and role set to null.
    assertNull(maniesEEOneStateOrig.getKey());
    assertNull(maniesEEOneStateOrig.getRole());
    // Ensure eeOne.getLoadedState() returns null for collection afterQuery flush.
    assertNull(eeOne.getLoadedValue("manies"));
    // Ensure the session in maniesEEOneStateOrig has been unset.
    assertNull(maniesEEOneStateOrig.getSession());
    s.getTransaction().commit();
    s.close();
}
Also used : EntityEntry(org.hibernate.engine.spi.EntityEntry) AbstractPersistentCollection(org.hibernate.collection.internal.AbstractPersistentCollection) CollectionEntry(org.hibernate.engine.spi.CollectionEntry) Session(org.hibernate.Session) Test(org.junit.Test) TestForIssue(org.hibernate.testing.TestForIssue)

Aggregations

EntityEntry (org.hibernate.engine.spi.EntityEntry)79 Serializable (java.io.Serializable)22 EntityPersister (org.hibernate.persister.entity.EntityPersister)21 Session (org.hibernate.Session)18 Test (org.junit.Test)17 CollectionEntry (org.hibernate.engine.spi.CollectionEntry)16 AbstractPersistentCollection (org.hibernate.collection.internal.AbstractPersistentCollection)12 EntityKey (org.hibernate.engine.spi.EntityKey)12 TestForIssue (org.hibernate.testing.TestForIssue)12 AssertionFailure (org.hibernate.AssertionFailure)11 HibernateProxy (org.hibernate.proxy.HibernateProxy)11 HibernateException (org.hibernate.HibernateException)10 EventSource (org.hibernate.event.spi.EventSource)9 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)8 TransientObjectException (org.hibernate.TransientObjectException)7 PersistentCollection (org.hibernate.collection.spi.PersistentCollection)7 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)6 Status (org.hibernate.engine.spi.Status)6 LazyInitializer (org.hibernate.proxy.LazyInitializer)6 EntityRegionAccessStrategy (org.hibernate.cache.spi.access.EntityRegionAccessStrategy)5