Skip to content

Commit

Permalink
HHH-15649 Additional performance fixes relating to Klass's _secondary…
Browse files Browse the repository at this point in the history
…_super_cache interaction with entity enhancement
  • Loading branch information
Sanne committed Nov 1, 2022
1 parent 3be1c29 commit dd7cbe8
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 59 deletions.
22 changes: 10 additions & 12 deletions hibernate-core/src/main/java/org/hibernate/Hibernate.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@

import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.HibernateIterator;
import org.hibernate.engine.internal.ManagedTypeHelper;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.collection.spi.LazyInitializable;

import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;

/**
* <ul>
* <li>Provides access to the full range of Hibernate built-in types. <tt>Type</tt>
Expand Down Expand Up @@ -66,9 +66,8 @@ public static void initialize(Object proxy) throws HibernateException {
else if ( proxy instanceof LazyInitializable ) {
( (LazyInitializable) proxy ).forceInitialization();
}
else if ( proxy instanceof PersistentAttributeInterceptable ) {
final PersistentAttributeInterceptable interceptable = (PersistentAttributeInterceptable) proxy;
final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
else if ( isPersistentAttributeInterceptable( proxy ) ) {
final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( proxy ).$$_hibernate_getInterceptor();
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
( (EnhancementAsProxyLazinessInterceptor) interceptor ).forceInitialize( proxy, null );
}
Expand All @@ -86,10 +85,8 @@ public static boolean isInitialized(Object proxy) {
if ( proxy instanceof HibernateProxy ) {
return !( (HibernateProxy) proxy ).getHibernateLazyInitializer().isUninitialized();
}
else if ( ManagedTypeHelper.isPersistentAttributeInterceptable( proxy ) ) {
final PersistentAttributeInterceptable asPersistentAttributeInterceptable = ManagedTypeHelper.asPersistentAttributeInterceptable(
proxy );
final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable.$$_hibernate_getInterceptor();
else if ( isPersistentAttributeInterceptable( proxy ) ) {
final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( proxy ).$$_hibernate_getInterceptor();
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
return false;
}
Expand Down Expand Up @@ -204,8 +201,9 @@ public static boolean isPropertyInitialized(Object proxy, String propertyName) {
entity = proxy;
}

if ( entity instanceof PersistentAttributeInterceptable ) {
PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();

if ( isPersistentAttributeInterceptable( entity ) ) {
PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( entity ).$$_hibernate_getInterceptor();
if ( interceptor instanceof BytecodeLazyAttributeInterceptor ) {
return ( (BytecodeLazyAttributeInterceptor) interceptor ).isAttributeLoaded( propertyName );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
import org.hibernate.bytecode.enhance.spi.CollectionTracker;
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.ManagedTypeHelper;
import org.hibernate.engine.spi.SelfDirtinessTracker;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.persister.entity.EntityPersister;

import static org.hibernate.engine.internal.ManagedTypeHelper.asSelfDirtinessTracker;
import static org.hibernate.engine.internal.ManagedTypeHelper.isSelfDirtinessTracker;

/**
* Interceptor that loads attributes lazily
*
Expand Down Expand Up @@ -155,13 +159,14 @@ public String toString() {
}

private void takeCollectionSizeSnapshot(Object target, String fieldName, Object value) {
if ( value instanceof Collection && target instanceof SelfDirtinessTracker ) {
if ( value instanceof Collection && isSelfDirtinessTracker( target ) ) {
// This must be called first, so that we remember that there is a collection out there,
// even if we don't know its size (see below).
CollectionTracker tracker = ( (SelfDirtinessTracker) target ).$$_hibernate_getCollectionTracker();
final SelfDirtinessTracker trackerAsSDT = asSelfDirtinessTracker( target );
CollectionTracker tracker = trackerAsSDT.$$_hibernate_getCollectionTracker();
if ( tracker == null ) {
( (SelfDirtinessTracker) target ).$$_hibernate_clearDirtyAttributes();
tracker = ( (SelfDirtinessTracker) target ).$$_hibernate_getCollectionTracker();
trackerAsSDT.$$_hibernate_clearDirtyAttributes();
tracker = trackerAsSDT.$$_hibernate_getCollectionTracker();
}

if ( value instanceof PersistentCollection && !( (PersistentCollection) value ).wasInitialized() ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ public static boolean isManaged(final Object entity) {
return entity instanceof EnhancedEntity || entity instanceof Managed;
}

/**
* @param entity
* @return true if and only if the entity implements {@see ManagedEntity}
*/
public static boolean isManagedEntity(Object entity) {
return entity instanceof EnhancedEntity || entity instanceof ManagedEntity;
}

/**
* @param type
* @return true if and only if the type is assignable to a {@see PersistentAttributeInterceptable} type.
Expand Down Expand Up @@ -176,4 +184,5 @@ public static SelfDirtinessTracker asSelfDirtinessTracker(final Object entity) {
return (SelfDirtinessTracker) entity;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.ManagedTypeHelper;
import org.hibernate.engine.loading.internal.LoadContexts;
import org.hibernate.engine.spi.AssociationKey;
import org.hibernate.engine.spi.BatchFetchQueue;
Expand Down Expand Up @@ -74,6 +73,9 @@

import org.jboss.logging.Logger;

import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;

/**
* A <strong>stateful</strong> implementation of the {@link PersistenceContext} contract meaning that we maintain this
* state throughout the life of the persistence context.
Expand Down Expand Up @@ -609,9 +611,8 @@ public boolean reassociateIfUninitializedProxy(Object value) throws MappingExcep
}

// or an uninitialized enhanced entity ("bytecode proxy")...
if ( value instanceof PersistentAttributeInterceptable ) {
final PersistentAttributeInterceptable bytecodeProxy = (PersistentAttributeInterceptable) value;
final BytecodeLazyAttributeInterceptor interceptor = (BytecodeLazyAttributeInterceptor) bytecodeProxy.$$_hibernate_getInterceptor();
if ( isPersistentAttributeInterceptable( value ) ) {
final BytecodeLazyAttributeInterceptor interceptor = (BytecodeLazyAttributeInterceptor) asPersistentAttributeInterceptable( value ).$$_hibernate_getInterceptor();
if ( interceptor != null ) {
interceptor.setSession( getSession() );
}
Expand Down Expand Up @@ -677,9 +678,8 @@ public Object unproxyAndReassociate(Object maybeProxy) throws HibernateException
//initialize + unwrap the object and return it
return li.getImplementation();
}
else if ( ManagedTypeHelper.isPersistentAttributeInterceptable( maybeProxy ) ) {
final PersistentAttributeInterceptable interceptable = ManagedTypeHelper.asPersistentAttributeInterceptable( maybeProxy );
final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
else if ( isPersistentAttributeInterceptable( maybeProxy ) ) {
final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( maybeProxy ).$$_hibernate_getInterceptor();
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
( (EnhancementAsProxyLazinessInterceptor) interceptor ).forceInitialize( maybeProxy, null );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.hibernate.classic.Lifecycle;
import org.hibernate.engine.internal.Cascade;
import org.hibernate.engine.internal.CascadePoint;
import org.hibernate.engine.internal.ManagedTypeHelper;
import org.hibernate.engine.internal.Versioning;
import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.engine.spi.EntityEntry;
Expand Down Expand Up @@ -107,9 +108,7 @@ protected Serializable saveWithGeneratedId(
boolean requiresImmediateIdAccess) {
callbackRegistry.preCreate( entity );

if ( entity instanceof SelfDirtinessTracker ) {
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
}
ManagedTypeHelper.processIfSelfDirtinessTracker( entity, SelfDirtinessTracker::$$_hibernate_clearDirtyAttributes );

EntityPersister persister = source.getEntityPersister( entityName, entity );
Serializable generatedId = persister.getIdentifierGenerator().generate( source, entity );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,7 @@ private boolean isUpdateNecessary(final FlushEntityEvent event, final boolean mi
return true;
}
else {
if ( SelfDirtinessTracker.class.isInstance( event.getEntity() ) ) {
( (SelfDirtinessTracker) event.getEntity() ).$$_hibernate_clearDirtyAttributes();
}
ManagedTypeHelper.processIfSelfDirtinessTracker( event.getEntity(), SelfDirtinessTracker::$$_hibernate_clearDirtyAttributes );
event.getSession()
.getFactory()
.getCustomEntityDirtinessStrategy()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.engine.internal.Cascade;
import org.hibernate.engine.internal.CascadePoint;
import org.hibernate.engine.internal.ManagedTypeHelper;
import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.engine.spi.CascadingActions;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SelfDirtinessTracker;
import org.hibernate.engine.spi.SessionFactoryImplementor;
Expand All @@ -42,6 +42,10 @@
import org.hibernate.type.ForeignKeyDirection;
import org.hibernate.type.TypeHelper;

import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
import static org.hibernate.engine.internal.ManagedTypeHelper.asSelfDirtinessTracker;
import static org.hibernate.engine.internal.ManagedTypeHelper.isSelfDirtinessTracker;

/**
* Defines the default copy event listener used by hibernate for copying entities
* in response to generated copy events.
Expand Down Expand Up @@ -111,9 +115,8 @@ public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateExcepti
entity = li.getImplementation();
}
}
else if ( original instanceof PersistentAttributeInterceptable ) {
final PersistentAttributeInterceptable interceptable = (PersistentAttributeInterceptable) original;
final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
else if ( ManagedTypeHelper.isPersistentAttributeInterceptable( original ) ) {
final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( original ).$$_hibernate_getInterceptor();
if ( interceptor instanceof EnhancementAsProxyLazinessInterceptor ) {
final EnhancementAsProxyLazinessInterceptor proxyInterceptor = (EnhancementAsProxyLazinessInterceptor) interceptor;
LOG.trace( "Ignoring uninitialized enhanced-proxy" );
Expand Down Expand Up @@ -249,9 +252,8 @@ protected void entityIsTransient(MergeEvent event, Map copyCache) {

event.setResult( copy );

if ( copy instanceof PersistentAttributeInterceptable ) {
final PersistentAttributeInterceptable interceptable = (PersistentAttributeInterceptable) copy;
final PersistentAttributeInterceptor interceptor = interceptable.$$_hibernate_getInterceptor();
if ( ManagedTypeHelper.isPersistentAttributeInterceptable( copy ) ) {
final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( copy ).$$_hibernate_getInterceptor();
if ( interceptor == null ) {
persister.getBytecodeEnhancementMetadata().injectInterceptor( copy, id, session );
}
Expand Down Expand Up @@ -363,11 +365,11 @@ private Object unproxyManagedForDetachedMerging(
return source.getPersistenceContextInternal().unproxy( managed );
}

if ( incoming instanceof PersistentAttributeInterceptable
if ( ManagedTypeHelper.isPersistentAttributeInterceptable( incoming )
&& persister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {

final PersistentAttributeInterceptor incomingInterceptor = ( (PersistentAttributeInterceptable) incoming ).$$_hibernate_getInterceptor();
final PersistentAttributeInterceptor managedInterceptor = ( (PersistentAttributeInterceptable) managed ).$$_hibernate_getInterceptor();
final PersistentAttributeInterceptor incomingInterceptor = asPersistentAttributeInterceptable( incoming ).$$_hibernate_getInterceptor();
final PersistentAttributeInterceptor managedInterceptor = asPersistentAttributeInterceptable( managed ).$$_hibernate_getInterceptor();

// todo - do we need to specially handle the case where both `incoming` and `managed` are initialized, but
// with different attributes initialized?
Expand All @@ -392,12 +394,13 @@ private Object unproxyManagedForDetachedMerging(

private void markInterceptorDirty(final Object entity, final Object target, EntityPersister persister) {
// for enhanced entities, copy over the dirty attributes
if ( entity instanceof SelfDirtinessTracker && target instanceof SelfDirtinessTracker ) {
if ( isSelfDirtinessTracker( entity ) && isSelfDirtinessTracker( target ) ) {
// clear, because setting the embedded attributes dirties them
( (SelfDirtinessTracker) target ).$$_hibernate_clearDirtyAttributes();
final SelfDirtinessTracker castedTarget = asSelfDirtinessTracker( target );
castedTarget.$$_hibernate_clearDirtyAttributes();

for ( String fieldName : ( (SelfDirtinessTracker) entity ).$$_hibernate_getDirtyAttributes() ) {
( (SelfDirtinessTracker) target ).$$_hibernate_trackChange( fieldName );
for ( String fieldName : asSelfDirtinessTracker( entity ).$$_hibernate_getDirtyAttributes() ) {
castedTarget.$$_hibernate_trackChange( fieldName );
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.hibernate.HibernateException;
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.ManagedTypeHelper;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.event.spi.EventSource;
Expand All @@ -31,8 +32,8 @@ public class DirtyCollectionSearchVisitor extends AbstractVisitor {
public DirtyCollectionSearchVisitor(Object entity, EventSource session, boolean[] propertyVersionability) {
super( session );
EnhancementAsProxyLazinessInterceptor interceptor = null;
if ( entity instanceof PersistentAttributeInterceptable ) {
if ( ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor() instanceof EnhancementAsProxyLazinessInterceptor ) {
if ( ManagedTypeHelper.isPersistentAttributeInterceptable( entity ) ) {
if ( ManagedTypeHelper.asPersistentAttributeInterceptable( entity ).$$_hibernate_getInterceptor() instanceof EnhancementAsProxyLazinessInterceptor ) {
interceptor = (EnhancementAsProxyLazinessInterceptor) ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.ManagedTypeHelper;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.SessionImplementor;
Expand Down Expand Up @@ -107,8 +108,8 @@ final Object processArrayOrNewCollection(Object collection, CollectionType colle
return null;
}
else {
if ( entity instanceof PersistentAttributeInterceptable ) {
if ( ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor() instanceof EnhancementAsProxyLazinessInterceptor ) {
if ( ManagedTypeHelper.isPersistentAttributeInterceptable( entity ) ) {
if ( ManagedTypeHelper.asPersistentAttributeInterceptable( entity ).$$_hibernate_getInterceptor() instanceof EnhancementAsProxyLazinessInterceptor ) {
return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import org.hibernate.Hibernate;
import org.hibernate.MappingException;
import org.hibernate.engine.internal.ManagedTypeHelper;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.ManagedEntity;
import org.hibernate.engine.spi.SessionFactoryImplementor;
Expand Down Expand Up @@ -70,8 +71,8 @@ public Object getIdentifier(Object entity) {
if ( entity instanceof HibernateProxy ) {
return ((HibernateProxy) entity).getHibernateLazyInitializer().getInternalIdentifier();
}
else if ( entity instanceof ManagedEntity ) {
EntityEntry entityEntry = ((ManagedEntity) entity).$$_hibernate_getEntityEntry();
else if ( ManagedTypeHelper.isManagedEntity( entity ) ) {
EntityEntry entityEntry = ManagedTypeHelper.asManagedEntity( entity ).$$_hibernate_getEntityEntry();
if ( entityEntry != null ) {
return entityEntry.getId();
}
Expand Down
Loading

0 comments on commit dd7cbe8

Please sign in to comment.