Search in sources :

Example 1 with PersistenceContext

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

the class TestAutoFlushBeforeQueryExecution method testAutoflushIsNotRequiredWithUnrelatedCollectionChange.

@Test
public void testAutoflushIsNotRequiredWithUnrelatedCollectionChange() {
    Session s = openSession();
    Transaction txn = s.beginTransaction();
    Publisher publisher = new Publisher();
    publisher.setName("name");
    s.save(publisher);
    assertTrue("autoflush entity create", s.createQuery("from Publisher p").list().size() == 1);
    publisher.setName("name");
    assertTrue("autoflush entity update", s.createQuery("from Publisher p where p.name='name'").list().size() == 1);
    UnrelatedEntity unrelatedEntity = new UnrelatedEntity();
    s.save(unrelatedEntity);
    txn.commit();
    s.close();
    s = openSession();
    txn = s.beginTransaction();
    unrelatedEntity = (UnrelatedEntity) s.get(UnrelatedEntity.class, unrelatedEntity.getId());
    publisher = (Publisher) s.get(Publisher.class, publisher.getId());
    assertTrue(publisher.getAuthors().isEmpty());
    final PersistenceContext persistenceContext = ((SessionImplementor) s).getPersistenceContext();
    final ActionQueue actionQueue = ((SessionImpl) s).getActionQueue();
    assertEquals(1, persistenceContext.getCollectionEntries().size());
    assertEquals(1, persistenceContext.getCollectionsByKey().size());
    assertTrue(persistenceContext.getCollectionEntries().containsKey(publisher.getAuthors()));
    assertTrue(persistenceContext.getCollectionsByKey().values().contains(publisher.getAuthors()));
    assertEquals(0, actionQueue.numberOfCollectionRemovals());
    Author author1 = new Author();
    author1.setPublisher(publisher);
    publisher.getAuthors().add(author1);
    assertTrue(s.createQuery("from UnrelatedEntity").list().size() == 1);
    assertEquals(2, persistenceContext.getCollectionEntries().size());
    assertEquals(1, persistenceContext.getCollectionsByKey().size());
    assertTrue(persistenceContext.getCollectionEntries().containsKey(publisher.getAuthors()));
    assertTrue(persistenceContext.getCollectionEntries().containsKey(author1.getBooks()));
    assertTrue(persistenceContext.getCollectionsByKey().values().contains(publisher.getAuthors()));
    assertEquals(0, actionQueue.numberOfCollectionRemovals());
    author1.setPublisher(null);
    s.delete(author1);
    publisher.getAuthors().clear();
    assertEquals(0, actionQueue.numberOfCollectionRemovals());
    assertTrue(s.createQuery("from UnrelatedEntity").list().size() == 1);
    assertEquals(2, persistenceContext.getCollectionEntries().size());
    assertEquals(1, persistenceContext.getCollectionsByKey().size());
    assertTrue(persistenceContext.getCollectionEntries().containsKey(publisher.getAuthors()));
    assertTrue(persistenceContext.getCollectionEntries().containsKey(author1.getBooks()));
    assertTrue(persistenceContext.getCollectionsByKey().values().contains(publisher.getAuthors()));
    assertEquals(0, actionQueue.numberOfCollectionRemovals());
    Set<Author> authorsOld = publisher.getAuthors();
    publisher.setAuthors(new HashSet<Author>());
    Author author2 = new Author();
    author2.setName("author2");
    author2.setPublisher(publisher);
    publisher.getAuthors().add(author2);
    List results = s.createQuery("from UnrelatedEntity").list();
    assertEquals(1, results.size());
    assertEquals(4, persistenceContext.getCollectionEntries().size());
    assertEquals(1, persistenceContext.getCollectionsByKey().size());
    assertTrue(persistenceContext.getCollectionEntries().containsKey(publisher.getAuthors()));
    assertTrue(persistenceContext.getCollectionEntries().containsKey(author2.getBooks()));
    assertTrue(persistenceContext.getCollectionEntries().containsKey(authorsOld));
    assertTrue(persistenceContext.getCollectionEntries().containsKey(author1.getBooks()));
    assertTrue(persistenceContext.getCollectionsByKey().values().contains(authorsOld));
    assertEquals(0, actionQueue.numberOfCollectionRemovals());
    s.flush();
    assertEquals(2, persistenceContext.getCollectionEntries().size());
    assertEquals(2, persistenceContext.getCollectionsByKey().size());
    assertTrue(persistenceContext.getCollectionEntries().containsKey(publisher.getAuthors()));
    assertTrue(persistenceContext.getCollectionEntries().containsKey(author2.getBooks()));
    assertTrue(persistenceContext.getCollectionsByKey().values().contains(publisher.getAuthors()));
    assertTrue(persistenceContext.getCollectionsByKey().values().contains(author2.getBooks()));
    assertEquals(0, actionQueue.numberOfCollectionRemovals());
    s.delete(publisher);
    assertTrue("autoflush delete", s.createQuery("from UnrelatedEntity").list().size() == 1);
    s.delete(unrelatedEntity);
    txn.commit();
    s.close();
}
Also used : ActionQueue(org.hibernate.engine.spi.ActionQueue) Transaction(org.hibernate.Transaction) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) SessionImplementor(org.hibernate.engine.spi.SessionImplementor) List(java.util.List) SessionImpl(org.hibernate.internal.SessionImpl) Session(org.hibernate.Session) Test(org.junit.Test)

Example 2 with PersistenceContext

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

the class AbstractCollectionPersister method getSubselectInitializer.

private CollectionInitializer getSubselectInitializer(Serializable key, SharedSessionContractImplementor session) {
    if (!isSubselectLoadable()) {
        return null;
    }
    final PersistenceContext persistenceContext = session.getPersistenceContext();
    SubselectFetch subselect = persistenceContext.getBatchFetchQueue().getSubselect(session.generateEntityKey(key, getOwnerEntityPersister()));
    if (subselect == null) {
        return null;
    } else {
        // Take care of any entities that might have
        // been evicted!
        Iterator iter = subselect.getResult().iterator();
        while (iter.hasNext()) {
            if (!persistenceContext.containsEntity((EntityKey) iter.next())) {
                iter.remove();
            }
        }
        // Run a subquery loader
        return createSubselectInitializer(subselect, session);
    }
}
Also used : EntityKey(org.hibernate.engine.spi.EntityKey) SubselectFetch(org.hibernate.engine.spi.SubselectFetch) Iterator(java.util.Iterator) PersistenceContext(org.hibernate.engine.spi.PersistenceContext)

Example 3 with PersistenceContext

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

the class CollectionReferenceInitializerImpl method finishUpRow.

@Override
public void finishUpRow(ResultSet resultSet, ResultSetProcessingContextImpl context) {
    try {
        // read the collection key for this reference for the current row.
        final PersistenceContext persistenceContext = context.getSession().getPersistenceContext();
        final Serializable collectionRowKey = (Serializable) collectionReference.getCollectionPersister().readKey(resultSet, aliases.getCollectionColumnAliases().getSuffixedKeyAliases(), context.getSession());
        if (collectionRowKey != null) {
            if (log.isDebugEnabled()) {
                log.debugf("Found row of collection: %s", MessageHelper.collectionInfoString(collectionReference.getCollectionPersister(), collectionRowKey, context.getSession().getFactory()));
            }
            Object collectionOwner = findCollectionOwner(collectionRowKey, resultSet, context);
            PersistentCollection rowCollection = persistenceContext.getLoadContexts().getCollectionLoadContext(resultSet).getLoadingCollection(collectionReference.getCollectionPersister(), collectionRowKey);
            if (rowCollection != null) {
                rowCollection.readFrom(resultSet, collectionReference.getCollectionPersister(), aliases.getCollectionColumnAliases(), collectionOwner);
            }
        } else {
            final Serializable optionalKey = findCollectionOwnerKey(context);
            if (optionalKey != null) {
                // since what we have is an empty collection
                if (log.isDebugEnabled()) {
                    log.debugf("Result set contains (possibly empty) collection: %s", MessageHelper.collectionInfoString(collectionReference.getCollectionPersister(), optionalKey, context.getSession().getFactory()));
                }
                // handle empty collection
                persistenceContext.getLoadContexts().getCollectionLoadContext(resultSet).getLoadingCollection(collectionReference.getCollectionPersister(), optionalKey);
            }
        }
    // else no collection element, but also no owner
    } catch (SQLException sqle) {
        // TODO: would be nice to have the SQL string that failed...
        throw context.getSession().getFactory().getSQLExceptionHelper().convert(sqle, "could not read next row of results");
    }
}
Also used : PersistentCollection(org.hibernate.collection.spi.PersistentCollection) Serializable(java.io.Serializable) SQLException(java.sql.SQLException) PersistenceContext(org.hibernate.engine.spi.PersistenceContext)

Example 4 with PersistenceContext

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

the class TwoPhaseLoad method postLoad.

/**
 * PostLoad cannot occur during initializeEntity, as that call occurs *before*
 * the Set collections are added to the persistence context by Loader.
 * Without the split, LazyInitializationExceptions can occur in the Entity's
 * postLoad if it acts upon the collection.
 *
 * HHH-6043
 *
 * @param entity The entity
 * @param session The Session
 * @param postLoadEvent The (re-used) post-load event
 */
public static void postLoad(final Object entity, final SharedSessionContractImplementor session, final PostLoadEvent postLoadEvent) {
    if (session.isEventSource()) {
        final PersistenceContext persistenceContext = session.getPersistenceContext();
        final EntityEntry entityEntry = persistenceContext.getEntry(entity);
        postLoadEvent.setEntity(entity).setId(entityEntry.getId()).setPersister(entityEntry.getPersister());
        final EventListenerGroup<PostLoadEventListener> listenerGroup = session.getFactory().getServiceRegistry().getService(EventListenerRegistry.class).getEventListenerGroup(EventType.POST_LOAD);
        for (PostLoadEventListener listener : listenerGroup.listeners()) {
            listener.onPostLoad(postLoadEvent);
        }
    }
}
Also used : EntityEntry(org.hibernate.engine.spi.EntityEntry) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) PostLoadEventListener(org.hibernate.event.spi.PostLoadEventListener) EventListenerRegistry(org.hibernate.event.service.spi.EventListenerRegistry)

Example 5 with PersistenceContext

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

the class TwoPhaseLoad method doInitializeEntity.

private static void doInitializeEntity(final Object entity, final EntityEntry entityEntry, final boolean readOnly, final SharedSessionContractImplementor session, final PreLoadEvent preLoadEvent) throws HibernateException {
    final PersistenceContext persistenceContext = session.getPersistenceContext();
    final EntityPersister persister = entityEntry.getPersister();
    final Serializable id = entityEntry.getId();
    final Object[] hydratedState = entityEntry.getLoadedState();
    final boolean debugEnabled = LOG.isDebugEnabled();
    if (debugEnabled) {
        LOG.debugf("Resolving associations for %s", MessageHelper.infoString(persister, id, session.getFactory()));
    }
    String entityName = persister.getEntityName();
    String[] propertyNames = persister.getPropertyNames();
    final Type[] types = persister.getPropertyTypes();
    for (int i = 0; i < hydratedState.length; i++) {
        final Object value = hydratedState[i];
        Boolean overridingEager = getOverridingEager(session, entityName, propertyNames[i], types[i]);
        if (value == LazyPropertyInitializer.UNFETCHED_PROPERTY) {
            // No resolution is necessary, unless the lazy property is a collection.
            if (types[i].isCollectionType()) {
                // IMPLEMENTATION NOTE: this is a lazy collection property on a bytecode-enhanced entity.
                // HHH-10989: We need to resolve the collection so that a CollectionReference is added to StatefulPersistentContext.
                // As mentioned above, hydratedState[i] needs to remain LazyPropertyInitializer.UNFETCHED_PROPERTY
                // so do not assign the resolved, unitialized PersistentCollection back to hydratedState[i].
                types[i].resolve(value, session, entity, overridingEager);
            }
        } else if (value != PropertyAccessStrategyBackRefImpl.UNKNOWN) {
            // we know value != LazyPropertyInitializer.UNFETCHED_PROPERTY
            hydratedState[i] = types[i].resolve(value, session, entity, overridingEager);
        }
    }
    // Must occur after resolving identifiers!
    if (session.isEventSource()) {
        preLoadEvent.setEntity(entity).setState(hydratedState).setId(id).setPersister(persister);
        final EventListenerGroup<PreLoadEventListener> listenerGroup = session.getFactory().getServiceRegistry().getService(EventListenerRegistry.class).getEventListenerGroup(EventType.PRE_LOAD);
        for (PreLoadEventListener listener : listenerGroup.listeners()) {
            listener.onPreLoad(preLoadEvent);
        }
    }
    persister.setPropertyValues(entity, hydratedState);
    final SessionFactoryImplementor factory = session.getFactory();
    if (persister.canWriteToCache() && session.getCacheMode().isPutEnabled()) {
        if (debugEnabled) {
            LOG.debugf("Adding entity to second-level cache: %s", MessageHelper.infoString(persister, id, session.getFactory()));
        }
        final Object version = Versioning.getVersion(hydratedState, persister);
        final CacheEntry entry = persister.buildCacheEntry(entity, hydratedState, version, session);
        final EntityDataAccess cache = persister.getCacheAccessStrategy();
        final Object cacheKey = cache.generateCacheKey(id, persister, factory, session.getTenantIdentifier());
        // we need to be careful not to clobber the lock here in the cache so that it can be rolled back if need be
        if (session.getPersistenceContext().wasInsertedDuringTransaction(persister, id)) {
            cache.update(session, cacheKey, persister.getCacheEntryStructure().structure(entry), version, version);
        } else {
            final SessionEventListenerManager eventListenerManager = session.getEventListenerManager();
            try {
                eventListenerManager.cachePutStart();
                final boolean put = cache.putFromLoad(session, cacheKey, persister.getCacheEntryStructure().structure(entry), version, useMinimalPuts(session, entityEntry));
                if (put && factory.getStatistics().isStatisticsEnabled()) {
                    factory.getStatistics().entityCachePut(StatsHelper.INSTANCE.getRootEntityRole(persister), cache.getRegion().getName());
                }
            } finally {
                eventListenerManager.cachePutEnd();
            }
        }
    }
    if (persister.hasNaturalIdentifier()) {
        persistenceContext.getNaturalIdHelper().cacheNaturalIdCrossReferenceFromLoad(persister, id, persistenceContext.getNaturalIdHelper().extractNaturalIdValues(hydratedState, persister));
    }
    boolean isReallyReadOnly = readOnly;
    if (!persister.isMutable()) {
        isReallyReadOnly = true;
    } else {
        final Object proxy = persistenceContext.getProxy(entityEntry.getEntityKey());
        if (proxy != null) {
            // there is already a proxy for this impl
            // only set the status to read-only if the proxy is read-only
            isReallyReadOnly = ((HibernateProxy) proxy).getHibernateLazyInitializer().isReadOnly();
        }
    }
    if (isReallyReadOnly) {
        // no need to take a snapshot - this is a
        // performance optimization, but not really
        // important, except for entities with huge
        // mutable property values
        persistenceContext.setEntryStatus(entityEntry, Status.READ_ONLY);
    } else {
        // take a snapshot
        TypeHelper.deepCopy(hydratedState, persister.getPropertyTypes(), persister.getPropertyUpdateability(), // after setting values to object
        hydratedState, session);
        persistenceContext.setEntryStatus(entityEntry, Status.MANAGED);
    }
    persister.afterInitialize(entity, session);
    if (debugEnabled) {
        LOG.debugf("Done materializing entity %s", MessageHelper.infoString(persister, id, session.getFactory()));
    }
    if (factory.getStatistics().isStatisticsEnabled()) {
        factory.getStatistics().loadEntity(persister.getEntityName());
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Serializable(java.io.Serializable) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) PreLoadEventListener(org.hibernate.event.spi.PreLoadEventListener) CacheEntry(org.hibernate.cache.spi.entry.CacheEntry) HibernateProxy(org.hibernate.proxy.HibernateProxy) EventListenerRegistry(org.hibernate.event.service.spi.EventListenerRegistry) EventType(org.hibernate.event.spi.EventType) Type(org.hibernate.type.Type) SessionEventListenerManager(org.hibernate.engine.spi.SessionEventListenerManager) EntityDataAccess(org.hibernate.cache.spi.access.EntityDataAccess)

Aggregations

PersistenceContext (org.hibernate.engine.spi.PersistenceContext)35 Serializable (java.io.Serializable)10 EntityKey (org.hibernate.engine.spi.EntityKey)9 EntityPersister (org.hibernate.persister.entity.EntityPersister)9 EntityEntry (org.hibernate.engine.spi.EntityEntry)8 List (java.util.List)7 EventSource (org.hibernate.event.spi.EventSource)7 PersistentCollection (org.hibernate.collection.spi.PersistentCollection)6 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)6 ArrayList (java.util.ArrayList)5 AssertionFailure (org.hibernate.AssertionFailure)4 SessionImplementor (org.hibernate.engine.spi.SessionImplementor)4 SessionImpl (org.hibernate.internal.SessionImpl)4 CollectionPersister (org.hibernate.persister.collection.CollectionPersister)4 Type (org.hibernate.type.Type)4 EntityDataAccess (org.hibernate.cache.spi.access.EntityDataAccess)3 StatefulPersistenceContext (org.hibernate.engine.internal.StatefulPersistenceContext)3 CollectionEntry (org.hibernate.engine.spi.CollectionEntry)3 CollectionKey (org.hibernate.engine.spi.CollectionKey)3 EventType (org.hibernate.event.spi.EventType)3