Search in sources :

Example 86 with EntityEntry

use of org.hibernate.engine.spi.EntityEntry in project webofneeds by researchstudio-sat.

the class ParentAwareFlushEventListener method updated.

private boolean updated(FlushEntityEvent event) {
    final EntityEntry entry = event.getEntityEntry();
    final Object entity = event.getEntity();
    int[] dirtyProperties;
    EntityPersister persister = entry.getPersister();
    final Object[] values = event.getPropertyValues();
    SessionImplementor session = event.getSession();
    if (event.hasDatabaseSnapshot()) {
        dirtyProperties = persister.findModified(event.getDatabaseSnapshot(), values, entity, session);
    } else {
        dirtyProperties = persister.findDirty(values, entry.getLoadedState(), entity, session);
    }
    return dirtyProperties != null;
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) EntityEntry(org.hibernate.engine.spi.EntityEntry) SessionImplementor(org.hibernate.engine.spi.SessionImplementor)

Example 87 with EntityEntry

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

the class DynamicBatchingEntityLoaderBuilder method performUnorderedMultiLoad.

@SuppressWarnings("unchecked")
protected List performUnorderedMultiLoad(OuterJoinLoadable persister, Serializable[] ids, SharedSessionContractImplementor session, MultiLoadOptions loadOptions) {
    assert !loadOptions.isOrderReturnEnabled();
    final List result = CollectionHelper.arrayList(ids.length);
    if (loadOptions.isSessionCheckingEnabled()) {
        // the user requested that we exclude ids corresponding to already managed
        // entities from the generated load SQL.  So here we will iterate all
        // incoming id values and see whether it corresponds to an existing
        // entity associated with the PC - if it does we add it to the result
        // list immediately and remove its id from the group of ids to load.
        boolean foundAnyManagedEntities = false;
        final List<Serializable> nonManagedIds = new ArrayList<Serializable>();
        for (Serializable id : ids) {
            final EntityKey entityKey = new EntityKey(id, persister);
            final Object managedEntity = session.getPersistenceContext().getEntity(entityKey);
            if (managedEntity != null) {
                if (!loadOptions.isReturnOfDeletedEntitiesEnabled()) {
                    final EntityEntry entry = session.getPersistenceContext().getEntry(managedEntity);
                    if (entry.getStatus() == Status.DELETED || entry.getStatus() == Status.GONE) {
                        continue;
                    }
                }
                foundAnyManagedEntities = true;
                result.add(managedEntity);
            } else {
                nonManagedIds.add(id);
            }
        }
        if (foundAnyManagedEntities) {
            if (nonManagedIds.isEmpty()) {
                // all of the given ids were already associated with the Session
                return result;
            } else {
                // over-write the ids to be loaded with the collection of
                // just non-managed ones
                ids = nonManagedIds.toArray((Serializable[]) Array.newInstance(ids.getClass().getComponentType(), nonManagedIds.size()));
            }
        }
    }
    final LockOptions lockOptions = (loadOptions.getLockOptions() == null) ? new LockOptions(LockMode.NONE) : loadOptions.getLockOptions();
    int numberOfIdsLeft = ids.length;
    final int maxBatchSize;
    if (loadOptions.getBatchSize() != null && loadOptions.getBatchSize() > 0) {
        maxBatchSize = loadOptions.getBatchSize();
    } else {
        maxBatchSize = session.getJdbcServices().getJdbcEnvironment().getDialect().getDefaultBatchLoadSizingStrategy().determineOptimalBatchLoadSize(persister.getIdentifierType().getColumnSpan(session.getFactory()), numberOfIdsLeft);
    }
    int idPosition = 0;
    while (numberOfIdsLeft > 0) {
        int batchSize = Math.min(numberOfIdsLeft, maxBatchSize);
        final DynamicEntityLoader batchingLoader = new DynamicEntityLoader(persister, batchSize, lockOptions, session.getFactory(), session.getLoadQueryInfluencers());
        Serializable[] idsInBatch = new Serializable[batchSize];
        System.arraycopy(ids, idPosition, idsInBatch, 0, batchSize);
        QueryParameters qp = buildMultiLoadQueryParameters(persister, idsInBatch, lockOptions);
        result.addAll(batchingLoader.doEntityBatchFetch(session, qp, idsInBatch));
        numberOfIdsLeft = numberOfIdsLeft - batchSize;
        idPosition += batchSize;
    }
    return result;
}
Also used : Serializable(java.io.Serializable) LockOptions(org.hibernate.LockOptions) ArrayList(java.util.ArrayList) QueryParameters(org.hibernate.engine.spi.QueryParameters) EntityKey(org.hibernate.engine.spi.EntityKey) EntityEntry(org.hibernate.engine.spi.EntityEntry) ArrayList(java.util.ArrayList) List(java.util.List)

Example 88 with EntityEntry

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

the class AbstractEntityTuplizer method persistTransientEntity.

private static Serializable persistTransientEntity(Object entity, SharedSessionContractImplementor session) {
    assert session != null;
    LOG.debug("Performing implicit derived identity cascade");
    final PersistEvent event = new PersistEvent(null, entity, (EventSource) session);
    for (PersistEventListener listener : persistEventListeners(session)) {
        listener.onPersist(event);
    }
    final EntityEntry pcEntry = session.getPersistenceContext().getEntry(entity);
    if (pcEntry == null || pcEntry.getId() == null) {
        throw new HibernateException("Unable to process implicit derived identity cascade");
    }
    return pcEntry.getId();
}
Also used : PersistEventListener(org.hibernate.event.spi.PersistEventListener) EntityEntry(org.hibernate.engine.spi.EntityEntry) HibernateException(org.hibernate.HibernateException) PersistEvent(org.hibernate.event.spi.PersistEvent)

Example 89 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 90 with EntityEntry

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

the class UnversionedNoCascadeDereferencedCollectionTest method testGetAndReplaceCollection.

@Test
@TestForIssue(jiraKey = "HHH-9777")
public void testGetAndReplaceCollection() {
    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.get(UnversionedNoCascadeOne.class, one.getId());
    // When returned by Session.get(), one.getManies() will return a PersistentCollection;
    // the EntityEntry loaded state should contain the same PersistentCollection.
    eeOne = getEntityEntry(s, one);
    assertNotNull(one.getManies());
    AbstractPersistentCollection maniesEEOneStateOrig = (AbstractPersistentCollection) eeOne.getLoadedValue("manies");
    assertSame(one.getManies(), 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());
    // replace collection
    one.setManies(new HashSet<Many>());
    s.flush();
    // Ensure the same EntityEntry is being used.
    assertSame(eeOne, getEntityEntry(s, one));
    // 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());
    // one.getManies() should be "wrapped" by a PersistentCollection now; role, key, and session should be set properly.
    assertTrue(PersistentCollection.class.isInstance(one.getManies()));
    assertEquals(role, ((PersistentCollection) one.getManies()).getRole());
    assertEquals(one.getId(), ((PersistentCollection) one.getManies()).getKey());
    assertSame(s, ((AbstractPersistentCollection) one.getManies()).getSession());
    // Ensure eeOne.getLoadedState() contains the new collection.
    assertSame(one.getManies(), eeOne.getLoadedValue("manies"));
    // Ensure there is a new CollectionEntry for the new collection and that role, persister, and key are set properly.
    CollectionEntry ceManiesAfterReplace = getCollectionEntry(s, (PersistentCollection) one.getManies());
    assertNotNull(ceManiesAfterReplace);
    assertEquals(role, ceManiesAfterReplace.getRole());
    assertSame(sessionFactory().getCollectionPersister(role), ceManiesAfterReplace.getLoadedPersister());
    assertEquals(one.getId(), ceManiesAfterReplace.getKey());
    // Ensure the session in maniesEEOneStateOrig has been unset.
    assertNull(maniesEEOneStateOrig.getSession());
    s.getTransaction().commit();
    s.close();
}
Also used : PersistentCollection(org.hibernate.collection.spi.PersistentCollection) AbstractPersistentCollection(org.hibernate.collection.internal.AbstractPersistentCollection) 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)164 EntityPersister (org.hibernate.persister.entity.EntityPersister)45 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)44 EntityKey (org.hibernate.engine.spi.EntityKey)33 CollectionEntry (org.hibernate.engine.spi.CollectionEntry)29 EventSource (org.hibernate.event.spi.EventSource)29 TestForIssue (org.hibernate.testing.TestForIssue)26 Serializable (java.io.Serializable)24 HibernateProxy (org.hibernate.proxy.HibernateProxy)23 Test (org.junit.Test)23 HibernateException (org.hibernate.HibernateException)21 Session (org.hibernate.Session)20 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)20 Status (org.hibernate.engine.spi.Status)20 Test (org.junit.jupiter.api.Test)18 Type (org.hibernate.type.Type)17 AssertionFailure (org.hibernate.AssertionFailure)16 TransientObjectException (org.hibernate.TransientObjectException)12 EntityDataAccess (org.hibernate.cache.spi.access.EntityDataAccess)12 AbstractPersistentCollection (org.hibernate.collection.internal.AbstractPersistentCollection)12