Search in sources :

Example 1 with PersistentAttributeInterceptable

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

the class BytecodeEnhancementMetadataPojoImpl method injectInterceptor.

@Override
public LazyAttributeLoadingInterceptor injectInterceptor(Object entity, SharedSessionContractImplementor session) {
    if (!enhancedForLazyLoading) {
        throw new NotInstrumentedException("Entity class [" + entityClass.getName() + "] is not enhanced for lazy loading");
    }
    if (!entityClass.isInstance(entity)) {
        throw new IllegalArgumentException(String.format("Passed entity instance [%s] is not of expected type [%s]", entity, getEntityName()));
    }
    final LazyAttributeLoadingInterceptor interceptor = new LazyAttributeLoadingInterceptor(getEntityName(), lazyAttributesMetadata.getLazyAttributeNames(), session);
    ((PersistentAttributeInterceptable) entity).$$_hibernate_setInterceptor(interceptor);
    return interceptor;
}
Also used : NotInstrumentedException(org.hibernate.bytecode.spi.NotInstrumentedException) LazyAttributeLoadingInterceptor(org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor) PersistentAttributeInterceptable(org.hibernate.engine.spi.PersistentAttributeInterceptable)

Example 2 with PersistentAttributeInterceptable

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

the class PersistenceUtilHelper method isLoadedWithoutReference.

/**
	 * Is the given attribute (by name) loaded?  This form must take care to not access the attribute (trigger
	 * initialization).
	 *
	 * @param entity The entity
	 * @param attributeName The name of the attribute to check
	 * @param cache The cache we maintain of attribute resolutions
	 *
	 * @return The LoadState
	 */
public static LoadState isLoadedWithoutReference(Object entity, String attributeName, MetadataCache cache) {
    boolean sureFromUs = false;
    if (entity instanceof HibernateProxy) {
        LazyInitializer li = ((HibernateProxy) entity).getHibernateLazyInitializer();
        if (li.isUninitialized()) {
            // we have an uninitialized proxy, the attribute cannot be loaded
            return LoadState.NOT_LOADED;
        } else {
            // swap the proxy with target (for proper class name resolution)
            entity = li.getImplementation();
        }
        sureFromUs = true;
    }
    // we are instrumenting but we can't assume we are the only ones
    if (entity instanceof PersistentAttributeInterceptable) {
        final LazyAttributeLoadingInterceptor interceptor = extractInterceptor((PersistentAttributeInterceptable) entity);
        final boolean isInitialized = interceptor == null || interceptor.isAttributeLoaded(attributeName);
        LoadState state;
        if (isInitialized && interceptor != null) {
            // it's ours, we can read
            try {
                final Class entityClass = entity.getClass();
                final Object attributeValue = cache.getClassMetadata(entityClass).getAttributeAccess(attributeName).extractValue(entity);
                state = isLoaded(attributeValue);
                // it's ours so we know it's loaded
                if (state == LoadState.UNKNOWN) {
                    state = LoadState.LOADED;
                }
            } catch (AttributeExtractionException ignore) {
                state = LoadState.UNKNOWN;
            }
        } else if (interceptor != null) {
            state = LoadState.NOT_LOADED;
        } else if (sureFromUs) {
            // it's ours, we can read
            try {
                final Class entityClass = entity.getClass();
                final Object attributeValue = cache.getClassMetadata(entityClass).getAttributeAccess(attributeName).extractValue(entity);
                state = isLoaded(attributeValue);
                // it's ours so we know it's loaded
                if (state == LoadState.UNKNOWN) {
                    state = LoadState.LOADED;
                }
            } catch (AttributeExtractionException ignore) {
                state = LoadState.UNKNOWN;
            }
        } else {
            state = LoadState.UNKNOWN;
        }
        return state;
    } else {
        return LoadState.UNKNOWN;
    }
}
Also used : LazyInitializer(org.hibernate.proxy.LazyInitializer) LazyAttributeLoadingInterceptor(org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor) PersistentAttributeInterceptable(org.hibernate.engine.spi.PersistentAttributeInterceptable) LoadState(javax.persistence.spi.LoadState) HibernateProxy(org.hibernate.proxy.HibernateProxy)

Example 3 with PersistentAttributeInterceptable

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

the class AbstractEntityPersister method initializeLazyProperty.

public Object initializeLazyProperty(String fieldName, Object entity, SharedSessionContractImplementor session) {
    final EntityEntry entry = session.getPersistenceContext().getEntry(entity);
    final InterceptorImplementor interceptor = ((PersistentAttributeInterceptable) entity).$$_hibernate_getInterceptor();
    assert interceptor != null : "Expecting bytecode interceptor to be non-null";
    if (hasCollections()) {
        final Type type = getPropertyType(fieldName);
        if (type.isCollectionType()) {
            // we have a condition where a collection attribute is being access via enhancement:
            // 		we can circumvent all the rest and just return the PersistentCollection
            final CollectionType collectionType = (CollectionType) type;
            final CollectionPersister persister = factory.getMetamodel().collectionPersister(collectionType.getRole());
            // Get/create the collection, and make sure it is initialized!  This initialized part is
            // different from proxy-based scenarios where we have to create the PersistentCollection
            // reference "ahead of time" to add as a reference to the proxy.  For bytecode solutions
            // we are not creating the PersistentCollection ahead of time, but instead we are creating
            // it on first request through the enhanced entity.
            // see if there is already a collection instance associated with the session
            // 		NOTE : can this ever happen?
            final Serializable key = getCollectionKey(persister, entity, entry, session);
            PersistentCollection collection = session.getPersistenceContext().getCollection(new CollectionKey(persister, key));
            if (collection == null) {
                collection = collectionType.instantiate(session, persister, key);
                collection.setOwner(entity);
                session.getPersistenceContext().addUninitializedCollection(persister, collection, key);
            }
            // HHH-11161 Initialize, if the collection is not extra lazy
            if (!persister.isExtraLazy()) {
                session.initializeCollection(collection, false);
            }
            interceptor.attributeInitialized(fieldName);
            if (collectionType.isArrayType()) {
                session.getPersistenceContext().addCollectionHolder(collection);
            }
            // update the "state" of the entity's EntityEntry to over-write UNFETCHED_PROPERTY reference
            // for the collection to the just loaded collection
            final EntityEntry ownerEntry = session.getPersistenceContext().getEntry(entity);
            if (ownerEntry == null) {
                // not good
                throw new AssertionFailure("Could not locate EntityEntry for the collection owner in the PersistenceContext");
            }
            ownerEntry.overwriteLoadedStateCollectionValue(fieldName, collection);
            // EARLY EXIT!!!
            return collection;
        }
    }
    final Serializable id = session.getContextEntityIdentifier(entity);
    if (entry == null) {
        throw new HibernateException("entity is not associated with the session: " + id);
    }
    if (LOG.isTraceEnabled()) {
        LOG.tracev("Initializing lazy properties of: {0}, field access: {1}", MessageHelper.infoString(this, id, getFactory()), fieldName);
    }
    if (session.getCacheMode().isGetEnabled() && hasCache() && isLazyPropertiesCacheable()) {
        final EntityRegionAccessStrategy cache = getCacheAccessStrategy();
        final Object cacheKey = cache.generateCacheKey(id, this, session.getFactory(), session.getTenantIdentifier());
        final Object ce = CacheHelper.fromSharedCache(session, cacheKey, cache);
        if (ce != null) {
            final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory);
            final Object initializedValue = initializeLazyPropertiesFromCache(fieldName, entity, session, entry, cacheEntry);
            interceptor.attributeInitialized(fieldName);
            // NOTE EARLY EXIT!!!
            return initializedValue;
        }
    }
    return initializeLazyPropertiesFromDatastore(fieldName, entity, session, id, entry);
}
Also used : Serializable(java.io.Serializable) AssertionFailure(org.hibernate.AssertionFailure) HibernateException(org.hibernate.HibernateException) PersistentAttributeInterceptable(org.hibernate.engine.spi.PersistentAttributeInterceptable) EntityRegionAccessStrategy(org.hibernate.cache.spi.access.EntityRegionAccessStrategy) CollectionKey(org.hibernate.engine.spi.CollectionKey) StructuredCacheEntry(org.hibernate.cache.spi.entry.StructuredCacheEntry) UnstructuredCacheEntry(org.hibernate.cache.spi.entry.UnstructuredCacheEntry) CacheEntry(org.hibernate.cache.spi.entry.CacheEntry) PersistentCollection(org.hibernate.collection.spi.PersistentCollection) EntityEntry(org.hibernate.engine.spi.EntityEntry) AssociationType(org.hibernate.type.AssociationType) JoinType(org.hibernate.sql.JoinType) CollectionType(org.hibernate.type.CollectionType) EntityType(org.hibernate.type.EntityType) ComponentType(org.hibernate.type.ComponentType) CompositeType(org.hibernate.type.CompositeType) VersionType(org.hibernate.type.VersionType) Type(org.hibernate.type.Type) CollectionPersister(org.hibernate.persister.collection.CollectionPersister) CollectionType(org.hibernate.type.CollectionType)

Example 4 with PersistentAttributeInterceptable

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

the class AbstractEntityPersister method initializeLazyPropertiesFromDatastore.

private Object initializeLazyPropertiesFromDatastore(final String fieldName, final Object entity, final SharedSessionContractImplementor session, final Serializable id, final EntityEntry entry) {
    if (!hasLazyProperties()) {
        throw new AssertionFailure("no lazy properties");
    }
    final InterceptorImplementor interceptor = ((PersistentAttributeInterceptable) entity).$$_hibernate_getInterceptor();
    assert interceptor != null : "Expecting bytecode interceptor to be non-null";
    LOG.trace("Initializing lazy properties from datastore");
    final String fetchGroup = getEntityMetamodel().getBytecodeEnhancementMetadata().getLazyAttributesMetadata().getFetchGroupName(fieldName);
    final List<LazyAttributeDescriptor> fetchGroupAttributeDescriptors = getEntityMetamodel().getBytecodeEnhancementMetadata().getLazyAttributesMetadata().getFetchGroupAttributeDescriptors(fetchGroup);
    final Set<String> initializedLazyAttributeNames = interceptor.getInitializedLazyAttributeNames();
    final String lazySelect = getSQLLazySelectString(fetchGroup);
    try {
        Object result = null;
        PreparedStatement ps = null;
        try {
            ResultSet rs = null;
            try {
                if (lazySelect != null) {
                    // null sql means that the only lazy properties
                    // are shared PK one-to-one associations which are
                    // handled differently in the Type#nullSafeGet code...
                    ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement(lazySelect);
                    getIdentifierType().nullSafeSet(ps, id, 1, session);
                    rs = session.getJdbcCoordinator().getResultSetReturn().extract(ps);
                    rs.next();
                }
                final Object[] snapshot = entry.getLoadedState();
                for (LazyAttributeDescriptor fetchGroupAttributeDescriptor : fetchGroupAttributeDescriptors) {
                    final boolean previousInitialized = initializedLazyAttributeNames.contains(fetchGroupAttributeDescriptor.getName());
                    if (previousInitialized) {
                        // its already been initialized (e.g. by a write) so we don't want to overwrite
                        continue;
                    }
                    final Object selectedValue = fetchGroupAttributeDescriptor.getType().nullSafeGet(rs, lazyPropertyColumnAliases[fetchGroupAttributeDescriptor.getLazyIndex()], session, entity);
                    final boolean set = initializeLazyProperty(fieldName, entity, session, snapshot, fetchGroupAttributeDescriptor.getLazyIndex(), selectedValue);
                    if (set) {
                        result = selectedValue;
                        interceptor.attributeInitialized(fetchGroupAttributeDescriptor.getName());
                    }
                }
            } finally {
                if (rs != null) {
                    session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release(rs, ps);
                }
            }
        } finally {
            if (ps != null) {
                session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release(ps);
                session.getJdbcCoordinator().afterStatementExecution();
            }
        }
        LOG.trace("Done initializing lazy properties");
        return result;
    } catch (SQLException sqle) {
        throw session.getJdbcServices().getSqlExceptionHelper().convert(sqle, "could not initialize lazy properties: " + MessageHelper.infoString(this, id, getFactory()), lazySelect);
    }
}
Also used : AssertionFailure(org.hibernate.AssertionFailure) SQLException(java.sql.SQLException) PersistentAttributeInterceptable(org.hibernate.engine.spi.PersistentAttributeInterceptable) PreparedStatement(java.sql.PreparedStatement) ResultSet(java.sql.ResultSet) LazyAttributeDescriptor(org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeDescriptor)

Example 5 with PersistentAttributeInterceptable

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

the class BasicEnhancementTestTask method execute.

public void execute() {
    SimpleEntity entity = new SimpleEntity();
    // Call the new ManagedEntity methods
    assertTyping(ManagedEntity.class, entity);
    ManagedEntity managedEntity = (ManagedEntity) entity;
    assertSame(entity, managedEntity.$$_hibernate_getEntityInstance());
    assertNull(managedEntity.$$_hibernate_getEntityEntry());
    managedEntity.$$_hibernate_setEntityEntry(EnhancerTestUtils.makeEntityEntry());
    assertNotNull(managedEntity.$$_hibernate_getEntityEntry());
    managedEntity.$$_hibernate_setEntityEntry(null);
    assertNull(managedEntity.$$_hibernate_getEntityEntry());
    managedEntity.$$_hibernate_setNextManagedEntity(managedEntity);
    managedEntity.$$_hibernate_setPreviousManagedEntity(managedEntity);
    assertSame(managedEntity, managedEntity.$$_hibernate_getNextManagedEntity());
    assertSame(managedEntity, managedEntity.$$_hibernate_getPreviousManagedEntity());
    // Add an attribute interceptor...
    assertTyping(PersistentAttributeInterceptable.class, entity);
    PersistentAttributeInterceptable interceptableEntity = (PersistentAttributeInterceptable) entity;
    assertNull(interceptableEntity.$$_hibernate_getInterceptor());
    interceptableEntity.$$_hibernate_setInterceptor(new ObjectAttributeMarkerInterceptor());
    assertNotNull(interceptableEntity.$$_hibernate_getInterceptor());
    assertNull(EnhancerTestUtils.getFieldByReflection(entity, "anUnspecifiedObject"));
    entity.setAnObject(new Object());
    assertSame(EnhancerTestUtils.getFieldByReflection(entity, "anUnspecifiedObject"), ObjectAttributeMarkerInterceptor.WRITE_MARKER);
    assertSame(entity.getAnObject(), ObjectAttributeMarkerInterceptor.READ_MARKER);
    entity.setAnObject(null);
    assertSame(EnhancerTestUtils.getFieldByReflection(entity, "anUnspecifiedObject"), ObjectAttributeMarkerInterceptor.WRITE_MARKER);
}
Also used : ManagedEntity(org.hibernate.engine.spi.ManagedEntity) PersistentAttributeInterceptable(org.hibernate.engine.spi.PersistentAttributeInterceptable)

Aggregations

PersistentAttributeInterceptable (org.hibernate.engine.spi.PersistentAttributeInterceptable)8 LazyAttributeLoadingInterceptor (org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor)4 AssertionFailure (org.hibernate.AssertionFailure)2 PersistentCollection (org.hibernate.collection.spi.PersistentCollection)2 EntityEntry (org.hibernate.engine.spi.EntityEntry)2 PersistentAttributeInterceptor (org.hibernate.engine.spi.PersistentAttributeInterceptor)2 Serializable (java.io.Serializable)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 HashMap (java.util.HashMap)1 IdentityHashMap (java.util.IdentityHashMap)1 Map (java.util.Map)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 LoadState (javax.persistence.spi.LoadState)1 HibernateException (org.hibernate.HibernateException)1 LazyAttributeDescriptor (org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeDescriptor)1 NotInstrumentedException (org.hibernate.bytecode.spi.NotInstrumentedException)1 EntityRegionAccessStrategy (org.hibernate.cache.spi.access.EntityRegionAccessStrategy)1 CacheEntry (org.hibernate.cache.spi.entry.CacheEntry)1