Search in sources :

Example 1 with EntityDataAccess

use of org.hibernate.cache.spi.access.EntityDataAccess in project hibernate-orm by hibernate.

the class AbstractEntityPersister method isTransient.

public Boolean isTransient(Object entity, SharedSessionContractImplementor session) throws HibernateException {
    final Serializable id;
    if (canExtractIdOutOfEntity()) {
        id = getIdentifier(entity, session);
    } else {
        id = null;
    }
    // identifier or no identifier property is unsaved!
    if (id == null) {
        return Boolean.TRUE;
    }
    // check the version unsaved-value, if appropriate
    final Object version = getVersion(entity);
    if (isVersioned()) {
        // let this take precedence if defined, since it works for
        // assigned identifiers
        Boolean result = entityMetamodel.getVersionProperty().getUnsavedValue().isUnsaved(version);
        if (result != null) {
            return result;
        }
    }
    // check the id unsaved-value
    Boolean result = entityMetamodel.getIdentifierProperty().getUnsavedValue().isUnsaved(id);
    if (result != null) {
        return result;
    }
    // check to see if it is in the second-level cache
    if (session.getCacheMode().isGetEnabled() && canReadFromCache()) {
        final EntityDataAccess cache = getCacheAccessStrategy();
        final Object ck = cache.generateCacheKey(id, this, session.getFactory(), session.getTenantIdentifier());
        final Object ce = CacheHelper.fromSharedCache(session, ck, getCacheAccessStrategy());
        if (ce != null) {
            return Boolean.FALSE;
        }
    }
    return null;
}
Also used : Serializable(java.io.Serializable) EntityDataAccess(org.hibernate.cache.spi.access.EntityDataAccess)

Example 2 with EntityDataAccess

use of org.hibernate.cache.spi.access.EntityDataAccess in project hibernate-orm by hibernate.

the class BasicStructuredCachingOfConvertedValueTest method basicCacheStructureTest.

@Test
@TestForIssue(jiraKey = "HHH-9615")
@SuppressWarnings("unchecked")
public void basicCacheStructureTest() {
    EntityPersister persister = sessionFactory().getMetamodel().entityPersisters().get(Address.class.getName());
    DomainDataRegion region = persister.getCacheAccessStrategy().getRegion();
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // test during store...
    PostalAreaConverter.clearCounts();
    Session session = openSession();
    session.getTransaction().begin();
    session.save(new Address(1, "123 Main St.", null, PostalArea._78729));
    session.getTransaction().commit();
    session.close();
    {
        inSession(s -> {
            final EntityDataAccess entityDataAccess = region.getEntityDataAccess(persister.getNavigableRole());
            final Object cacheKey = entityDataAccess.generateCacheKey(1, persister, sessionFactory(), null);
            final Object cachedItem = entityDataAccess.get(s, cacheKey);
            final Map<String, ?> state = (Map) cachedItem;
            // this is the point of the Jira.. that this "should be" the converted value
            assertThat(state.get("postalArea"), instanceOf(PostalArea.class));
        });
    }
    assertThat(PostalAreaConverter.toDatabaseCallCount, is(1));
    assertThat(PostalAreaConverter.toDomainCallCount, is(0));
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // test during load...
    PostalAreaConverter.clearCounts();
    sessionFactory().getCache().evictAll();
    session = openSession();
    session.getTransaction().begin();
    Address address = session.get(Address.class, 1);
    session.getTransaction().commit();
    session.close();
    {
        inSession(s -> {
            final EntityDataAccess entityDataAccess = region.getEntityDataAccess(persister.getNavigableRole());
            final Object cacheKey = entityDataAccess.generateCacheKey(1, persister, sessionFactory(), null);
            final Object cachedItem = entityDataAccess.get(s, cacheKey);
            final Map<String, ?> state = (Map) cachedItem;
            // this is the point of the Jira.. that this "should be" the converted value
            assertThat(state.get("postalArea"), instanceOf(PostalArea.class));
        });
    }
    assertThat(PostalAreaConverter.toDatabaseCallCount, is(0));
    assertThat(PostalAreaConverter.toDomainCallCount, is(1));
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // cleanup
    session = openSession();
    session.getTransaction().begin();
    session.delete(address);
    session.getTransaction().commit();
    session.close();
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) CoreMatchers.is(org.hamcrest.CoreMatchers.is) EntityPersister(org.hibernate.persister.entity.EntityPersister) BaseNonConfigCoreFunctionalTestCase(org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase) AvailableSettings(org.hibernate.cfg.AvailableSettings) CachingRegionFactory(org.hibernate.testing.cache.CachingRegionFactory) Session(org.hibernate.Session) EntityDataAccess(org.hibernate.cache.spi.access.EntityDataAccess) Test(org.junit.Test) CoreMatchers.instanceOf(org.hamcrest.CoreMatchers.instanceOf) TestForIssue(org.hibernate.testing.TestForIssue) Map(java.util.Map) DomainDataRegion(org.hibernate.cache.spi.DomainDataRegion) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) DomainDataRegion(org.hibernate.cache.spi.DomainDataRegion) Map(java.util.Map) Session(org.hibernate.Session) EntityDataAccess(org.hibernate.cache.spi.access.EntityDataAccess) Test(org.junit.Test) TestForIssue(org.hibernate.testing.TestForIssue)

Example 3 with EntityDataAccess

use of org.hibernate.cache.spi.access.EntityDataAccess 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)

Example 4 with EntityDataAccess

use of org.hibernate.cache.spi.access.EntityDataAccess in project hibernate-orm by hibernate.

the class EntityDeleteAction method execute.

@Override
public void execute() throws HibernateException {
    final Serializable id = getId();
    final EntityPersister persister = getPersister();
    final SharedSessionContractImplementor session = getSession();
    final Object instance = getInstance();
    final boolean veto = preDelete();
    Object version = this.version;
    if (persister.isVersionPropertyGenerated()) {
        // we need to grab the version value from the entity, otherwise
        // we have issues with generated-version entities that may have
        // multiple actions queued during the same flush
        version = persister.getVersion(instance);
    }
    final Object ck;
    if (persister.canWriteToCache()) {
        final EntityDataAccess cache = persister.getCacheAccessStrategy();
        ck = cache.generateCacheKey(id, persister, session.getFactory(), session.getTenantIdentifier());
        lock = cache.lockItem(session, ck, version);
    } else {
        ck = null;
    }
    if (!isCascadeDeleteEnabled && !veto) {
        persister.delete(id, version, instance, session);
    }
    // postDelete:
    // After actually deleting a row, record the fact that the instance no longer
    // exists on the database (needed for identity-column key generation), and
    // remove it from the session cache
    final PersistenceContext persistenceContext = session.getPersistenceContext();
    final EntityEntry entry = persistenceContext.removeEntry(instance);
    if (entry == null) {
        throw new AssertionFailure("possible nonthreadsafe access to session");
    }
    entry.postDelete();
    persistenceContext.removeEntity(entry.getEntityKey());
    persistenceContext.removeProxy(entry.getEntityKey());
    if (persister.canWriteToCache()) {
        persister.getCacheAccessStrategy().remove(session, ck);
    }
    persistenceContext.getNaturalIdHelper().removeSharedNaturalIdCrossReference(persister, id, naturalIdValues);
    postDelete();
    if (getSession().getFactory().getStatistics().isStatisticsEnabled() && !veto) {
        getSession().getFactory().getStatistics().deleteEntity(getPersister().getEntityName());
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Serializable(java.io.Serializable) EntityEntry(org.hibernate.engine.spi.EntityEntry) AssertionFailure(org.hibernate.AssertionFailure) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) EntityDataAccess(org.hibernate.cache.spi.access.EntityDataAccess)

Example 5 with EntityDataAccess

use of org.hibernate.cache.spi.access.EntityDataAccess in project hibernate-orm by hibernate.

the class EntityInsertAction method execute.

@Override
public void execute() throws HibernateException {
    nullifyTransientReferencesIfNotAlready();
    final EntityPersister persister = getPersister();
    final SharedSessionContractImplementor session = getSession();
    final Object instance = getInstance();
    final Serializable id = getId();
    final boolean veto = preInsert();
    if (!veto) {
        persister.insert(id, getState(), instance, session);
        PersistenceContext persistenceContext = session.getPersistenceContext();
        final EntityEntry entry = persistenceContext.getEntry(instance);
        if (entry == null) {
            throw new AssertionFailure("possible non-threadsafe access to session");
        }
        entry.postInsert(getState());
        if (persister.hasInsertGeneratedProperties()) {
            persister.processInsertGeneratedProperties(id, instance, getState(), session);
            if (persister.isVersionPropertyGenerated()) {
                version = Versioning.getVersion(getState(), persister);
            }
            entry.postUpdate(instance, getState(), version);
        }
        persistenceContext.registerInsertedKey(persister, getId());
    }
    final SessionFactoryImplementor factory = session.getFactory();
    if (isCachePutEnabled(persister, session)) {
        final CacheEntry ce = persister.buildCacheEntry(instance, getState(), version, session);
        cacheEntry = persister.getCacheEntryStructure().structure(ce);
        final EntityDataAccess cache = persister.getCacheAccessStrategy();
        final Object ck = cache.generateCacheKey(id, persister, factory, session.getTenantIdentifier());
        final boolean put = cacheInsert(persister, ck);
        if (put && factory.getStatistics().isStatisticsEnabled()) {
            factory.getStatistics().entityCachePut(StatsHelper.INSTANCE.getRootEntityRole(persister), cache.getRegion().getName());
        }
    }
    handleNaturalIdPostSaveNotifications(id);
    postInsert();
    if (factory.getStatistics().isStatisticsEnabled() && !veto) {
        factory.getStatistics().insertEntity(getPersister().getEntityName());
    }
    markExecuted();
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Serializable(java.io.Serializable) EntityEntry(org.hibernate.engine.spi.EntityEntry) AssertionFailure(org.hibernate.AssertionFailure) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) CacheEntry(org.hibernate.cache.spi.entry.CacheEntry) EntityDataAccess(org.hibernate.cache.spi.access.EntityDataAccess)

Aggregations

EntityDataAccess (org.hibernate.cache.spi.access.EntityDataAccess)24 EntityPersister (org.hibernate.persister.entity.EntityPersister)15 Serializable (java.io.Serializable)8 CacheEntry (org.hibernate.cache.spi.entry.CacheEntry)5 EntityEntry (org.hibernate.engine.spi.EntityEntry)5 AssertionFailure (org.hibernate.AssertionFailure)4 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)4 Map (java.util.Map)3 HibernateException (org.hibernate.HibernateException)3 DomainDataRegion (org.hibernate.cache.spi.DomainDataRegion)3 SoftLock (org.hibernate.cache.spi.access.SoftLock)3 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)3 SharedSessionContractImplementor (org.hibernate.engine.spi.SharedSessionContractImplementor)3 Test (org.junit.Test)3 CoreMatchers.instanceOf (org.hamcrest.CoreMatchers.instanceOf)2 CoreMatchers.is (org.hamcrest.CoreMatchers.is)2 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)2 LockMode (org.hibernate.LockMode)2 Session (org.hibernate.Session)2 CollectionDataAccess (org.hibernate.cache.spi.access.CollectionDataAccess)2