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;
}
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;
}
}
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);
}
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);
}
}
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);
}
Aggregations