HHH-15790 Make HibernateProxy also type-cache friendly
This commit is contained in:
parent
366a1e9c1d
commit
fbf469830c
|
@ -35,7 +35,9 @@ import org.hibernate.proxy.HibernateProxy;
|
|||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.collection.spi.LazyInitializable;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
|
||||
|
||||
/**
|
||||
|
@ -126,8 +128,8 @@ public final class Hibernate {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( proxy instanceof HibernateProxy ) {
|
||||
( (HibernateProxy) proxy ).getHibernateLazyInitializer().initialize();
|
||||
if ( isHibernateProxy( proxy ) ) {
|
||||
asHibernateProxy( proxy ).getHibernateLazyInitializer().initialize();
|
||||
}
|
||||
else if ( proxy instanceof LazyInitializable ) {
|
||||
( (LazyInitializable) proxy ).forceInitialization();
|
||||
|
@ -149,8 +151,9 @@ public final class Hibernate {
|
|||
* @return true if the argument is already initialized, or is not a proxy or collection
|
||||
*/
|
||||
public static boolean isInitialized(Object proxy) {
|
||||
if ( proxy instanceof HibernateProxy ) {
|
||||
return !( (HibernateProxy) proxy ).getHibernateLazyInitializer().isUninitialized();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy );
|
||||
if ( lazyInitializer != null ) {
|
||||
return !lazyInitializer.isUninitialized();
|
||||
}
|
||||
else if ( isPersistentAttributeInterceptable( proxy ) ) {
|
||||
final PersistentAttributeInterceptor interceptor = asPersistentAttributeInterceptable( proxy ).$$_hibernate_getInterceptor();
|
||||
|
@ -241,8 +244,9 @@ public final class Hibernate {
|
|||
@SuppressWarnings("unchecked")
|
||||
public static <T> Class<? extends T> getClass(T proxy) {
|
||||
Class<?> result;
|
||||
if ( proxy instanceof HibernateProxy ) {
|
||||
result = ( (HibernateProxy) proxy ).getHibernateLazyInitializer()
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy );
|
||||
if ( lazyInitializer != null ) {
|
||||
result = lazyInitializer
|
||||
.getImplementation()
|
||||
.getClass();
|
||||
}
|
||||
|
@ -280,13 +284,13 @@ public final class Hibernate {
|
|||
*/
|
||||
public static boolean isPropertyInitialized(Object proxy, String propertyName) {
|
||||
final Object entity;
|
||||
if ( proxy instanceof HibernateProxy ) {
|
||||
final LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( lazyInitializer.isUninitialized() ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
entity = li.getImplementation();
|
||||
entity = lazyInitializer.getImplementation();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -315,8 +319,8 @@ public final class Hibernate {
|
|||
* uninitialized proxy that is not associated with an open session.
|
||||
*/
|
||||
public static Object unproxy(Object proxy) {
|
||||
if ( proxy instanceof HibernateProxy ) {
|
||||
HibernateProxy hibernateProxy = (HibernateProxy) proxy;
|
||||
if ( isHibernateProxy( proxy ) ) {
|
||||
HibernateProxy hibernateProxy = asHibernateProxy( proxy );
|
||||
LazyInitializer initializer = hibernateProxy.getHibernateLazyInitializer();
|
||||
return initializer.getImplementation();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.bytecode.internal.bytebuddy;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.anyOf;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isFinalizer;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSynthetic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isVirtual;
|
||||
|
@ -26,6 +27,7 @@ import java.util.function.Function;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
|
||||
import org.hibernate.bytecode.spi.BasicProxyFactory;
|
||||
import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.securitymanager.SystemSecurityManager;
|
||||
import org.hibernate.proxy.ProxyConfiguration;
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.pretty.MessageHelper;
|
|||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
|
||||
|
||||
/**
|
||||
|
@ -347,9 +348,8 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
|||
return !enhancementAsProxyLazinessInterceptor.hasWrittenFieldNames();
|
||||
}
|
||||
}
|
||||
else if ( entity instanceof HibernateProxy ) {
|
||||
uninitializedProxy = ( (HibernateProxy) entity ).getHibernateLazyInitializer()
|
||||
.isUninitialized();
|
||||
else if ( isHibernateProxy( entity ) ) {
|
||||
uninitializedProxy = HibernateProxy.extractLazyInitializer( entity ).isUninitialized();
|
||||
}
|
||||
// we never have to check an uninitialized proxy
|
||||
return uninitializedProxy || !persister.hasCollections()
|
||||
|
|
|
@ -21,6 +21,8 @@ import org.hibernate.type.CompositeType;
|
|||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
|
||||
/**
|
||||
* Algorithms related to foreign key constraint transparency
|
||||
*
|
||||
|
@ -198,20 +200,20 @@ public final class ForeignKeys {
|
|||
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
|
||||
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
// if it's an uninitialized proxy it can only be
|
||||
// transient if we did an unloaded-delete on the
|
||||
// proxy itself, in which case there is no entry
|
||||
// for it, but its key has already been registered
|
||||
// as nullifiable
|
||||
final LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
Object entity = li.getImplementation( session );
|
||||
Object entity = lazyInitializer.getImplementation( session );
|
||||
if ( entity == null ) {
|
||||
return persistenceContext.containsDeletedUnloadedEntityKey(
|
||||
session.generateEntityKey(
|
||||
li.getIdentifier(),
|
||||
lazyInitializer.getIdentifier(),
|
||||
session.getFactory().getRuntimeMetamodels().getMappingMetamodel()
|
||||
.getEntityDescriptor( li.getEntityName() )
|
||||
.getEntityDescriptor( lazyInitializer.getEntityName() )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -255,7 +257,7 @@ public final class ForeignKeys {
|
|||
* @return {@code true} if the given entity is not transient (meaning it is either detached/persistent)
|
||||
*/
|
||||
public static boolean isNotTransient(String entityName, Object entity, Boolean assumed, SharedSessionContractImplementor session) {
|
||||
return entity instanceof HibernateProxy
|
||||
return isHibernateProxy( entity )
|
||||
|| session.getPersistenceContextInternal().isEntryFor( entity )
|
||||
// todo : shouldn't assumed be reversed here?
|
||||
|| !isTransient( entityName, entity, assumed, session );
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.hibernate.engine.spi.ManagedEntity;
|
|||
import org.hibernate.engine.spi.ManagedMappedSuperclass;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||
import org.hibernate.engine.spi.SelfDirtinessTracker;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiConsumer;
|
||||
|
@ -106,6 +107,18 @@ public final class ManagedTypeHelper {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @return true if and only if the entity implements {@see HibernateProxy}
|
||||
*/
|
||||
public static boolean isHibernateProxy(final Object entity) {
|
||||
if ( entity instanceof PrimeAmongSecondarySupertypes ) {
|
||||
PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) entity;
|
||||
return t.asHibernateProxy() != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entity
|
||||
* @return true if and only if the entity implements {@see PersistentAttributeInterceptable}
|
||||
|
|
|
@ -68,8 +68,10 @@ import org.hibernate.type.CollectionType;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asManagedEntity;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
|
||||
|
||||
/**
|
||||
|
@ -228,7 +230,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
if ( proxiesByKey != null ) {
|
||||
proxiesByKey.forEach( (k,o) -> {
|
||||
if ( o != null) {
|
||||
((HibernateProxy) o).getHibernateLazyInitializer().unsetSession();
|
||||
HibernateProxy.extractLazyInitializer( o ).unsetSession();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
@ -600,8 +602,8 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
if ( ! Hibernate.isInitialized( value ) ) {
|
||||
|
||||
// could be a proxy....
|
||||
if ( value instanceof HibernateProxy ) {
|
||||
final HibernateProxy proxy = (HibernateProxy) value;
|
||||
if ( isHibernateProxy( value ) ) {
|
||||
final HibernateProxy proxy = asHibernateProxy( value );
|
||||
final LazyInitializer li = proxy.getHibernateLazyInitializer();
|
||||
reassociateProxy( li, proxy );
|
||||
return true;
|
||||
|
@ -624,9 +626,9 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
|
||||
@Override
|
||||
public void reassociateProxy(Object value, Object id) throws MappingException {
|
||||
if ( value instanceof HibernateProxy ) {
|
||||
if ( isHibernateProxy( value ) ) {
|
||||
LOG.debugf( "Setting proxy identifier: %s", id );
|
||||
final HibernateProxy proxy = (HibernateProxy) value;
|
||||
final HibernateProxy proxy = asHibernateProxy( value );
|
||||
final LazyInitializer li = proxy.getHibernateLazyInitializer();
|
||||
li.setIdentifier( id );
|
||||
reassociateProxy( li, proxy );
|
||||
|
@ -654,8 +656,8 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
|
||||
@Override
|
||||
public Object unproxy(Object maybeProxy) throws HibernateException {
|
||||
if ( maybeProxy instanceof HibernateProxy ) {
|
||||
final HibernateProxy proxy = (HibernateProxy) maybeProxy;
|
||||
if ( isHibernateProxy( maybeProxy ) ) {
|
||||
final HibernateProxy proxy = asHibernateProxy( maybeProxy );
|
||||
final LazyInitializer li = proxy.getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
throw new PersistentObjectException(
|
||||
|
@ -672,8 +674,8 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
|
||||
@Override
|
||||
public Object unproxyAndReassociate(Object maybeProxy) throws HibernateException {
|
||||
if ( maybeProxy instanceof HibernateProxy ) {
|
||||
final HibernateProxy proxy = (HibernateProxy) maybeProxy;
|
||||
if ( isHibernateProxy( maybeProxy ) ) {
|
||||
final HibernateProxy proxy = asHibernateProxy( maybeProxy );
|
||||
final LazyInitializer li = proxy.getHibernateLazyInitializer();
|
||||
reassociateProxy( li, proxy );
|
||||
//initialize + unwrap the object and return it
|
||||
|
@ -722,7 +724,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
|
||||
// Similarly, if the original HibernateProxy is initialized, there
|
||||
// is again no point in creating a proxy. Just return the impl
|
||||
final HibernateProxy originalHibernateProxy = (HibernateProxy) proxy;
|
||||
final HibernateProxy originalHibernateProxy = asHibernateProxy( proxy );
|
||||
if ( !originalHibernateProxy.getHibernateLazyInitializer().isUninitialized() ) {
|
||||
final Object impl = originalHibernateProxy.getHibernateLazyInitializer().getImplementation();
|
||||
// can we return it?
|
||||
|
@ -734,7 +736,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
|
||||
|
||||
// Otherwise, create the narrowed proxy
|
||||
final HibernateProxy narrowedProxy = (HibernateProxy) persister.createProxy( key.getIdentifier(), session );
|
||||
final HibernateProxy narrowedProxy = asHibernateProxy( persister.createProxy( key.getIdentifier(), session ) );
|
||||
|
||||
// set the read-only/modifiable mode in the new proxy to what it was in the original proxy
|
||||
final boolean readOnlyOrig = originalHibernateProxy.getHibernateLazyInitializer().isReadOnly();
|
||||
|
@ -744,7 +746,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
}
|
||||
else {
|
||||
if ( object != null ) {
|
||||
final LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
|
||||
final LazyInitializer li = asHibernateProxy( proxy ).getHibernateLazyInitializer();
|
||||
li.setImplementation( object );
|
||||
}
|
||||
return proxy;
|
||||
|
@ -1316,8 +1318,8 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
if ( mergeMap != null ) {
|
||||
for ( Object o : mergeMap.entrySet() ) {
|
||||
final Entry<?,?> mergeMapEntry = (Entry<?,?>) o;
|
||||
if ( mergeMapEntry.getKey() instanceof HibernateProxy ) {
|
||||
final HibernateProxy proxy = (HibernateProxy) mergeMapEntry.getKey();
|
||||
if ( isHibernateProxy( mergeMapEntry.getKey() ) ) {
|
||||
final HibernateProxy proxy = asHibernateProxy( mergeMapEntry.getKey() );
|
||||
if ( persister.isSubclassEntityName( proxy.getHibernateLazyInitializer().getEntityName() ) ) {
|
||||
boolean found = isFoundInParent(
|
||||
propertyName,
|
||||
|
@ -1480,8 +1482,9 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
throw new AssertionFailure( "object must be non-null." );
|
||||
}
|
||||
boolean isReadOnly;
|
||||
if ( entityOrProxy instanceof HibernateProxy ) {
|
||||
isReadOnly = ( (HibernateProxy) entityOrProxy ).getHibernateLazyInitializer().isReadOnly();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entityOrProxy );
|
||||
if ( lazyInitializer != null ) {
|
||||
isReadOnly = lazyInitializer.isReadOnly();
|
||||
}
|
||||
else {
|
||||
final EntityEntry ee = getEntry( entityOrProxy );
|
||||
|
@ -1501,8 +1504,8 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
if ( isReadOnly( object ) == readOnly ) {
|
||||
return;
|
||||
}
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
final HibernateProxy proxy = (HibernateProxy) object;
|
||||
if ( isHibernateProxy( object ) ) {
|
||||
final HibernateProxy proxy = asHibernateProxy( object );
|
||||
setProxyReadOnly( proxy, readOnly );
|
||||
if ( Hibernate.isInitialized( proxy ) ) {
|
||||
setEntityReadOnly(
|
||||
|
@ -1516,8 +1519,8 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
// PersistenceContext.proxyFor( entity ) returns entity if there is no proxy for that entity
|
||||
// so need to check the return value to be sure it is really a proxy
|
||||
final Object maybeProxy = getSession().getPersistenceContextInternal().proxyFor( object );
|
||||
if ( maybeProxy instanceof HibernateProxy ) {
|
||||
setProxyReadOnly( (HibernateProxy) maybeProxy, readOnly );
|
||||
if ( isHibernateProxy( maybeProxy ) ) {
|
||||
setProxyReadOnly( asHibernateProxy( maybeProxy ), readOnly );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1689,7 +1692,8 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
rtn.hasNonReadOnlyEntities = ois.readBoolean();
|
||||
|
||||
int count = ois.readInt();
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
final boolean traceEnabled = LOG.isTraceEnabled();
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Starting deserialization of [" + count + "] entitiesByKey entries" );
|
||||
}
|
||||
rtn.entitiesByKey = CollectionHelper.mapOfSize(Math.max(count, INIT_COLL_SIZE));
|
||||
|
@ -1698,7 +1702,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
}
|
||||
|
||||
count = ois.readInt();
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Starting deserialization of [" + count + "] entitiesByUniqueKey entries" );
|
||||
}
|
||||
if ( count != 0 ) {
|
||||
|
@ -1709,26 +1713,27 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
}
|
||||
|
||||
count = ois.readInt();
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Starting deserialization of [" + count + "] proxiesByKey entries" );
|
||||
}
|
||||
for ( int i = 0; i < count; i++ ) {
|
||||
final EntityKey ek = EntityKey.deserialize( ois, sfi );
|
||||
final Object proxy = ois.readObject();
|
||||
if ( proxy instanceof HibernateProxy ) {
|
||||
( (HibernateProxy) proxy ).getHibernateLazyInitializer().setSession( session );
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy );
|
||||
if ( lazyInitializer != null ) {
|
||||
lazyInitializer.setSession( session );
|
||||
rtn.getOrInitializeProxiesByKey().put( ek, proxy );
|
||||
}
|
||||
else {
|
||||
// otherwise, the proxy was pruned during the serialization process
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Encountered pruned proxy" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count = ois.readInt();
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Starting deserialization of [" + count + "] entitySnapshotsByKey entries" );
|
||||
}
|
||||
rtn.entitySnapshotsByKey = CollectionHelper.mapOfSize(Math.max(count, INIT_COLL_SIZE));
|
||||
|
@ -1739,7 +1744,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
rtn.entityEntryContext = EntityEntryContext.deserialize( ois, rtn );
|
||||
|
||||
count = ois.readInt();
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Starting deserialization of [" + count + "] collectionsByKey entries" );
|
||||
}
|
||||
rtn.collectionsByKey = CollectionHelper.mapOfSize(Math.max(count, INIT_COLL_SIZE));
|
||||
|
@ -1751,7 +1756,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
}
|
||||
|
||||
count = ois.readInt();
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Starting deserialization of [" + count + "] collectionEntries entries" );
|
||||
}
|
||||
for ( int i = 0; i < count; i++ ) {
|
||||
|
@ -1762,7 +1767,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
}
|
||||
|
||||
count = ois.readInt();
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Starting deserialization of [" + count + "] arrayHolders entries" );
|
||||
}
|
||||
if ( count != 0 ) {
|
||||
|
@ -1773,7 +1778,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
}
|
||||
|
||||
count = ois.readInt();
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
if ( traceEnabled ) {
|
||||
LOG.trace( "Starting deserialization of [" + count + "] nullifiableEntityKey entries" );
|
||||
}
|
||||
rtn.nullifiableEntityKeys = new HashSet<>();
|
||||
|
|
|
@ -844,10 +844,10 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
public void unScheduleDeletion(EntityEntry entry, Object rescuedEntity) {
|
||||
if ( rescuedEntity instanceof HibernateProxy ) {
|
||||
LazyInitializer initializer = ( (HibernateProxy) rescuedEntity ).getHibernateLazyInitializer();
|
||||
if ( !initializer.isUninitialized() ) {
|
||||
rescuedEntity = initializer.getImplementation( session );
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( rescuedEntity );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( !lazyInitializer.isUninitialized() ) {
|
||||
rescuedEntity = lazyInitializer.getImplementation( session );
|
||||
}
|
||||
}
|
||||
if ( deletions != null ) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.engine.spi;
|
||||
|
||||
import org.hibernate.engine.internal.ManagedTypeHelper;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
/**
|
||||
* For a full explanation of the purpose of this interface
|
||||
|
@ -53,4 +54,8 @@ public interface PrimeAmongSecondarySupertypes {
|
|||
return null;
|
||||
}
|
||||
|
||||
default HibernateProxy asHibernateProxy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -98,14 +98,13 @@ public class DefaultDeleteEventListener implements DeleteEventListener, Callback
|
|||
|
||||
private boolean optimizeUnloadedDelete(DeleteEvent event) {
|
||||
final Object object = event.getObject();
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
HibernateProxy proxy = (HibernateProxy) object;
|
||||
LazyInitializer initializer = proxy.getHibernateLazyInitializer();
|
||||
if ( initializer.isUninitialized() ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( lazyInitializer.isUninitialized() ) {
|
||||
final EventSource source = event.getSession();
|
||||
final EntityPersister persister = source.getFactory().getMappingMetamodel()
|
||||
.findEntityDescriptor( initializer.getEntityName() );
|
||||
final Object id = initializer.getIdentifier();
|
||||
.findEntityDescriptor( lazyInitializer.getEntityName() );
|
||||
final Object id = lazyInitializer.getIdentifier();
|
||||
final EntityKey key = source.generateEntityKey( id, persister );
|
||||
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||
if ( !persistenceContext.containsEntity( key )
|
||||
|
|
|
@ -47,25 +47,25 @@ public class DefaultEvictEventListener implements EvictEventListener {
|
|||
if ( object == null ) {
|
||||
throw new NullPointerException( "null passed to Session.evict()" );
|
||||
}
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
final LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
final Object id = li.getInternalIdentifier();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
final Object id = lazyInitializer.getInternalIdentifier();
|
||||
if ( id == null ) {
|
||||
throw new IllegalArgumentException( "Could not determine identifier of proxy passed to evict()" );
|
||||
}
|
||||
final EntityPersister persister = source.getFactory()
|
||||
.getMappingMetamodel()
|
||||
.getEntityDescriptor( li.getEntityName() );
|
||||
.getEntityDescriptor( lazyInitializer.getEntityName() );
|
||||
final EntityKey key = source.generateEntityKey( id, persister );
|
||||
persistenceContext.removeProxy( key );
|
||||
if ( !li.isUninitialized() ) {
|
||||
if ( !lazyInitializer.isUninitialized() ) {
|
||||
final Object entity = persistenceContext.removeEntity( key );
|
||||
if ( entity != null ) {
|
||||
EntityEntry entry = persistenceContext.removeEntry( entity );
|
||||
doEvict( entity, key, entry.getPersister(), event.getSession() );
|
||||
}
|
||||
}
|
||||
li.unsetSession();
|
||||
lazyInitializer.unsetSession();
|
||||
}
|
||||
else {
|
||||
EntityEntry entry = persistenceContext.getEntry( object );
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.event.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NonUniqueObjectException;
|
||||
|
@ -298,11 +296,8 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
// existing proxy associated with the PC - and if so, use it
|
||||
final Object proxy = persistenceContext.getProxy( keyToLoad );
|
||||
if ( proxy != null ) {
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace( "Entity proxy found in session cache" );
|
||||
}
|
||||
if ( LOG.isDebugEnabled()
|
||||
&& ( (HibernateProxy) proxy ).getHibernateLazyInitializer().isUnwrap() ) {
|
||||
LOG.trace( "Entity proxy found in session cache" );
|
||||
if ( LOG.isDebugEnabled() && HibernateProxy.extractLazyInitializer( proxy ).isUnwrap() ) {
|
||||
LOG.debug( "Ignoring NO_PROXY to honor laziness" );
|
||||
}
|
||||
return persistenceContext.narrowProxy( proxy, persister, keyToLoad, null );
|
||||
|
@ -378,7 +373,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace( "Entity proxy found in session cache" );
|
||||
}
|
||||
final LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
|
||||
LazyInitializer li = HibernateProxy.extractLazyInitializer( proxy );
|
||||
if ( li.isUnwrap() ) {
|
||||
return li.getImplementation();
|
||||
}
|
||||
|
@ -601,8 +596,9 @@ public class DefaultLoadEventListener implements LoadEventListener {
|
|||
// persister/loader/initializer sensitive to this fact - possibly
|
||||
// passing LoadType along
|
||||
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
entity = ( (HibernateProxy) entity ).getHibernateLazyInitializer().getImplementation();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
|
||||
if ( lazyInitializer != null ) {
|
||||
entity = lazyInitializer.getImplementation();
|
||||
}
|
||||
|
||||
final StatisticsImplementor statistics = event.getSession().getFactory().getStatistics();
|
||||
|
|
|
@ -103,14 +103,14 @@ public class DefaultMergeEventListener
|
|||
// NOTE : `original` is the value being merged
|
||||
if ( original != null ) {
|
||||
final EventSource source = event.getSession();
|
||||
if ( original instanceof HibernateProxy ) {
|
||||
LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( original );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( lazyInitializer.isUninitialized() ) {
|
||||
LOG.trace( "Ignoring uninitialized proxy" );
|
||||
event.setResult( source.load( li.getEntityName(), li.getInternalIdentifier() ) );
|
||||
event.setResult( source.load( lazyInitializer.getEntityName(), lazyInitializer.getInternalIdentifier() ) );
|
||||
}
|
||||
else {
|
||||
doMerge( event, copiedAlready, li.getImplementation() );
|
||||
doMerge( event, copiedAlready, lazyInitializer.getImplementation() );
|
||||
}
|
||||
}
|
||||
else if ( isPersistentAttributeInterceptable( original ) ) {
|
||||
|
|
|
@ -62,15 +62,15 @@ public class DefaultPersistEventListener
|
|||
*/
|
||||
public void onPersist(PersistEvent event, PersistContext createCache) throws HibernateException {
|
||||
final Object object = event.getObject();
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
if ( li.getSession() != event.getSession() ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( lazyInitializer.isUninitialized() ) {
|
||||
if ( lazyInitializer.getSession() != event.getSession() ) {
|
||||
throw new PersistentObjectException( "uninitialized proxy passed to persist()" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
persist( event, createCache, li.getImplementation() );
|
||||
persist( event, createCache, lazyInitializer.getImplementation() );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
|
||||
/**
|
||||
* Defines the default listener used by Hibernate for handling save-update
|
||||
|
@ -57,8 +58,9 @@ public class DefaultSaveOrUpdateEventListener
|
|||
if ( requestedId != null ) {
|
||||
//assign the requested id to the proxy, *before*
|
||||
//reassociating the proxy
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
( (HibernateProxy) object ).getHibernateLazyInitializer().setIdentifier( requestedId );
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
lazyInitializer.setIdentifier( requestedId );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -697,8 +697,8 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
|
||||
@Override
|
||||
public String bestGuessEntityName(Object object) {
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
LazyInitializer initializer = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
final LazyInitializer initializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( initializer != null ) {
|
||||
// it is possible for this method to be called during flush processing,
|
||||
// so make certain that we do not accidentally initialize an uninitialized proxy
|
||||
if ( initializer.isUninitialized() ) {
|
||||
|
@ -1081,10 +1081,9 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
}
|
||||
|
||||
Class<?> clazz;
|
||||
if (bindValue instanceof HibernateProxy) {
|
||||
HibernateProxy proxy = (HibernateProxy) bindValue;
|
||||
LazyInitializer li = proxy.getHibernateLazyInitializer();
|
||||
clazz = li.getPersistentClass();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( bindValue );
|
||||
if ( lazyInitializer != null ) {
|
||||
clazz = lazyInitializer.getPersistentClass();
|
||||
}
|
||||
else {
|
||||
clazz = bindValue.getClass();
|
||||
|
|
|
@ -162,6 +162,7 @@ import static org.hibernate.cfg.AvailableSettings.JPA_LOCK_SCOPE;
|
|||
import static org.hibernate.cfg.AvailableSettings.JPA_LOCK_TIMEOUT;
|
||||
import static org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_RETRIEVE_MODE;
|
||||
import static org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_STORE_MODE;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_READ_ONLY;
|
||||
import static org.hibernate.jpa.LegacySpecHints.HINT_JAVAEE_LOCK_TIMEOUT;
|
||||
import static org.hibernate.jpa.LegacySpecHints.HINT_JAVAEE_QUERY_TIMEOUT;
|
||||
|
@ -534,8 +535,9 @@ public class SessionImpl
|
|||
throw new NullPointerException( "null object passed to getCurrentLockMode()" );
|
||||
}
|
||||
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation( this );
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
object = lazyInitializer.getImplementation( this );
|
||||
if ( object == null ) {
|
||||
return LockMode.NONE;
|
||||
}
|
||||
|
@ -1034,8 +1036,9 @@ public class SessionImpl
|
|||
fireLoadNoChecks( event, LoadEventListener.IMMEDIATE_LOAD );
|
||||
Object result = event.getResult();
|
||||
finishWithEventInstance( event );
|
||||
if ( result instanceof HibernateProxy ) {
|
||||
return ( (HibernateProxy) result ).getHibernateLazyInitializer().getImplementation();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( result );
|
||||
if ( lazyInitializer != null ) {
|
||||
return lazyInitializer.getImplementation();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1496,12 +1499,12 @@ public class SessionImpl
|
|||
public Object getIdentifier(Object object) throws HibernateException {
|
||||
checkOpen();
|
||||
checkTransactionSynchStatus();
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
if ( li.getSession() != this ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( lazyInitializer.getSession() != this ) {
|
||||
throw new TransientObjectException( "The proxy was not associated with this session" );
|
||||
}
|
||||
return li.getInternalIdentifier();
|
||||
return lazyInitializer.getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
EntityEntry entry = persistenceContext.getEntry( object );
|
||||
|
@ -1529,7 +1532,13 @@ public class SessionImpl
|
|||
}
|
||||
|
||||
private Object getProxyIdentifier(Object proxy) {
|
||||
return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxy );
|
||||
if ( lazyInitializer != null ) {
|
||||
return lazyInitializer.getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
throw new HibernateException( "Argument was not an HibernateProxy, which is a requirement for this method" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1542,23 +1551,23 @@ public class SessionImpl
|
|||
}
|
||||
|
||||
try {
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
//do not use proxiesByKey, since not all
|
||||
//proxies that point to this session's
|
||||
//instances are in that collection!
|
||||
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
if ( lazyInitializer.isUninitialized() ) {
|
||||
//if it is an uninitialized proxy, pointing
|
||||
//with this session, then when it is accessed,
|
||||
//the underlying instance will be "contained"
|
||||
return li.getSession() == this;
|
||||
return lazyInitializer.getSession() == this;
|
||||
}
|
||||
else {
|
||||
//if it is initialized, see if the underlying
|
||||
//instance is contained, since we need to
|
||||
//account for the fact that it might have been
|
||||
//evicted
|
||||
object = li.getImplementation();
|
||||
object = lazyInitializer.getImplementation();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1569,7 +1578,7 @@ public class SessionImpl
|
|||
delayedAfterCompletion();
|
||||
|
||||
if ( entry == null ) {
|
||||
if ( !(object instanceof HibernateProxy) && persistenceContext.getEntry( object ) == null ) {
|
||||
if ( ! ( isHibernateProxy( object ) ) && persistenceContext.getEntry( object ) == null ) {
|
||||
// check if it is even an entity -> if not throw an exception (per JPA)
|
||||
try {
|
||||
final String entityName = getEntityNameResolver().resolveEntityName( object );
|
||||
|
@ -1620,11 +1629,11 @@ public class SessionImpl
|
|||
}
|
||||
}
|
||||
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
final LazyInitializer li = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( li != null ) {
|
||||
//do not use proxiesByKey, since not all
|
||||
//proxies that point to this session's
|
||||
//instances are in that collection!
|
||||
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
//if it is an uninitialized proxy, pointing
|
||||
//with this session, then when it is accessed,
|
||||
|
@ -1693,14 +1702,14 @@ public class SessionImpl
|
|||
|
||||
@Override
|
||||
public String bestGuessEntityName(Object object) {
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
LazyInitializer initializer = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
// it is possible for this method to be called during flush processing,
|
||||
// so make certain that we do not accidentally initialize an uninitialized proxy
|
||||
if ( initializer.isUninitialized() ) {
|
||||
return initializer.getEntityName();
|
||||
if ( lazyInitializer.isUninitialized() ) {
|
||||
return lazyInitializer.getEntityName();
|
||||
}
|
||||
object = initializer.getImplementation();
|
||||
object = lazyInitializer.getImplementation();
|
||||
}
|
||||
EntityEntry entry = persistenceContext.getEntry( object );
|
||||
if ( entry == null ) {
|
||||
|
@ -1715,11 +1724,12 @@ public class SessionImpl
|
|||
public String getEntityName(Object object) {
|
||||
checkOpen();
|
||||
// checkTransactionSynchStatus();
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( !persistenceContext.containsProxy( object ) ) {
|
||||
throw new TransientObjectException( "proxy was not associated with the session" );
|
||||
}
|
||||
object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation();
|
||||
object = lazyInitializer.getImplementation();
|
||||
}
|
||||
|
||||
EntityEntry entry = persistenceContext.getEntry( object );
|
||||
|
@ -1732,9 +1742,9 @@ public class SessionImpl
|
|||
@Override @SuppressWarnings("unchecked")
|
||||
public <T> T getReference(T object) {
|
||||
checkOpen();
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
LazyInitializer initializer = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
return (T) getReference( initializer.getPersistentClass(), initializer.getIdentifier() );
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
return (T) getReference( lazyInitializer.getPersistentClass(), lazyInitializer.getIdentifier() );
|
||||
}
|
||||
else {
|
||||
EntityPersister persister = getEntityPersister( null, object );
|
||||
|
|
|
@ -328,7 +328,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.trace( "Entity proxy found in session cache" );
|
||||
}
|
||||
if ( LOG.isDebugEnabled() && ( (HibernateProxy) proxy ).getHibernateLazyInitializer().isUnwrap() ) {
|
||||
if ( LOG.isDebugEnabled() && HibernateProxy.extractLazyInitializer( proxy ).isUnwrap() ) {
|
||||
LOG.debug( "Ignoring NO_PROXY to honor laziness" );
|
||||
}
|
||||
|
||||
|
@ -387,8 +387,7 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
checkOpen();
|
||||
PersistenceContext persistenceContext = getPersistenceContext();
|
||||
if ( association instanceof HibernateProxy ) {
|
||||
LazyInitializer initializer =
|
||||
((HibernateProxy) association).getHibernateLazyInitializer();
|
||||
final LazyInitializer initializer = HibernateProxy.extractLazyInitializer( association );
|
||||
if ( initializer.isUninitialized() ) {
|
||||
String entityName = initializer.getEntityName();
|
||||
Object id = initializer.getIdentifier();
|
||||
|
@ -479,8 +478,9 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
|||
|
||||
@Override
|
||||
public String bestGuessEntityName(Object object) {
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
object = lazyInitializer.getImplementation();
|
||||
}
|
||||
return guessEntityName( object );
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -69,8 +70,9 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
|
|||
throw new IllegalArgumentException( "Passed entity cannot be null" );
|
||||
}
|
||||
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
return ((HibernateProxy) entity).getHibernateLazyInitializer().getInternalIdentifier();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
|
||||
if ( lazyInitializer != null ) {
|
||||
return lazyInitializer.getInternalIdentifier();
|
||||
}
|
||||
else if ( isManagedEntity( entity ) ) {
|
||||
EntityEntry entityEntry = asManagedEntity( entity ).$$_hibernate_getEntityEntry();
|
||||
|
|
|
@ -80,8 +80,9 @@ public final class PersistenceUtilHelper {
|
|||
* @return The appropriate LoadState (see above)
|
||||
*/
|
||||
public static LoadState isLoaded(Object reference) {
|
||||
if ( reference instanceof HibernateProxy ) {
|
||||
final boolean isInitialized = !( (HibernateProxy) reference ).getHibernateLazyInitializer().isUninitialized();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( reference );
|
||||
if ( lazyInitializer != null ) {
|
||||
final boolean isInitialized = !lazyInitializer.isUninitialized();
|
||||
return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
|
||||
}
|
||||
else if ( isPersistentAttributeInterceptable( reference ) ) {
|
||||
|
@ -118,15 +119,15 @@ public final class PersistenceUtilHelper {
|
|||
*/
|
||||
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() ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( lazyInitializer.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();
|
||||
entity = lazyInitializer.getImplementation();
|
||||
}
|
||||
sureFromUs = true;
|
||||
}
|
||||
|
@ -200,15 +201,15 @@ public final class PersistenceUtilHelper {
|
|||
* @return The LoadState
|
||||
*/
|
||||
public static LoadState isLoadedWithReference(Object entity, String attributeName, MetadataCache cache) {
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
final LazyInitializer li = ( (HibernateProxy) entity ).getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( lazyInitializer.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();
|
||||
entity = lazyInitializer.getImplementation();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -200,8 +200,8 @@ public abstract class BaseNaturalIdLoadAccessImpl<T> implements NaturalIdLoadOpt
|
|||
|
||||
if ( loaded != null ) {
|
||||
final EntityEntry entry;
|
||||
if ( loaded instanceof HibernateProxy ) {
|
||||
LazyInitializer lazyInitializer = ( (HibernateProxy) loaded ).getHibernateLazyInitializer();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( loaded );
|
||||
if ( lazyInitializer != null ) {
|
||||
entry = persistenceContext.getEntry( lazyInitializer.getImplementation() );
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -31,6 +31,9 @@ import org.hibernate.proxy.LazyInitializer;
|
|||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -210,8 +213,8 @@ public class IdentifierLoadAccessImpl<T> implements IdentifierLoadAccess<T>, Jav
|
|||
return;
|
||||
}
|
||||
|
||||
if ( result instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) result;
|
||||
if ( isHibernateProxy( result ) ) {
|
||||
final HibernateProxy hibernateProxy = asHibernateProxy( result );
|
||||
final LazyInitializer initializer = hibernateProxy.getHibernateLazyInitializer();
|
||||
if ( initializer.isUninitialized() ) {
|
||||
initializer.initialize();
|
||||
|
|
|
@ -431,7 +431,7 @@ public class CacheEntityLoaderHelper {
|
|||
if ( proxy != null ) {
|
||||
// there is already a proxy for this impl
|
||||
// only set the status to read-only if the proxy is read-only
|
||||
isReadOnly = ( (HibernateProxy) proxy ).getHibernateLazyInitializer().isReadOnly();
|
||||
isReadOnly = HibernateProxy.extractLazyInitializer( proxy ).isReadOnly();
|
||||
}
|
||||
else {
|
||||
isReadOnly = source.isDefaultReadOnly();
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.hibernate.metamodel.model.domain.NavigableRole;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
|
@ -144,16 +145,18 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
|
|||
|
||||
@Override
|
||||
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
|
||||
if ( lazyInitializer != null ) {
|
||||
return lazyInitializer.getIdentifier();
|
||||
}
|
||||
return propertyAccess.getGetter().get( entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdentifier(Object entity) {
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
|
||||
if ( lazyInitializer != null ) {
|
||||
return lazyInitializer.getIdentifier();
|
||||
}
|
||||
return propertyAccess.getGetter().get( entity );
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
|
@ -85,16 +86,18 @@ public class EmbeddedIdentifierMappingImpl
|
|||
|
||||
@Override
|
||||
public Object getIdentifier(Object entity, SharedSessionContractImplementor session) {
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
|
||||
if ( lazyInitializer != null ) {
|
||||
return lazyInitializer.getIdentifier();
|
||||
}
|
||||
return propertyAccess.getGetter().get( entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdentifier(Object entity) {
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
|
||||
if ( lazyInitializer != null ) {
|
||||
return lazyInitializer.getIdentifier();
|
||||
}
|
||||
return propertyAccess.getGetter().get( entity );
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.metamodel.mapping.SelectableMapping;
|
|||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.query.sqm.ComparisonOperator;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
|
@ -429,8 +430,11 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
|
|||
if ( targetObject == null ) {
|
||||
return null;
|
||||
}
|
||||
if ( refersToPrimaryKey && targetObject instanceof HibernateProxy ) {
|
||||
return ( (HibernateProxy) targetObject ).getHibernateLazyInitializer().getIdentifier();
|
||||
if ( refersToPrimaryKey ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( targetObject );
|
||||
if ( lazyInitializer != null ) {
|
||||
return lazyInitializer.getIdentifier();
|
||||
}
|
||||
}
|
||||
final ModelPart modelPart = side.getModelPart();
|
||||
if ( modelPart instanceof EntityIdentifierMapping ) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.PropertyAccessException;
|
|||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.property.access.internal.AbstractFieldSerialForm;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
|
||||
/**
|
||||
* Field-based implementation of Setter
|
||||
|
@ -68,8 +69,9 @@ public class SetterFieldImpl implements Setter {
|
|||
}
|
||||
else {
|
||||
final String valueType;
|
||||
if ( value instanceof HibernateProxy ) {
|
||||
valueType = ( (HibernateProxy) value ).getHibernateLazyInitializer().getEntityName();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( value );
|
||||
if ( lazyInitializer != null ) {
|
||||
valueType = lazyInitializer.getEntityName();
|
||||
}
|
||||
else {
|
||||
valueType = value.getClass().getTypeName();
|
||||
|
|
|
@ -7,12 +7,33 @@
|
|||
package org.hibernate.proxy;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes;
|
||||
|
||||
/**
|
||||
* Marker interface for entity proxies
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public interface HibernateProxy extends Serializable {
|
||||
public interface HibernateProxy extends Serializable, PrimeAmongSecondarySupertypes {
|
||||
|
||||
/**
|
||||
* Extract the LazyInitializer from the object, if
|
||||
* and only if the object is actually an HibernateProxy.
|
||||
* If not, null is returned.
|
||||
* @param object any entity
|
||||
* @return either null (if object is not an HibernateProxy) or the LazyInitializer of the HibernateProxy.
|
||||
*/
|
||||
static LazyInitializer extractLazyInitializer(final Object object) {
|
||||
if ( object instanceof PrimeAmongSecondarySupertypes ) {
|
||||
PrimeAmongSecondarySupertypes t = (PrimeAmongSecondarySupertypes) object;
|
||||
final HibernateProxy hibernateProxy = t.asHibernateProxy();
|
||||
if ( hibernateProxy != null ) {
|
||||
return hibernateProxy.getHibernateLazyInitializer();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform serialization-time write-replacement of this proxy.
|
||||
*
|
||||
|
@ -26,4 +47,14 @@ public interface HibernateProxy extends Serializable {
|
|||
* @return The lazy initializer.
|
||||
*/
|
||||
LazyInitializer getHibernateLazyInitializer();
|
||||
|
||||
/**
|
||||
* Special internal contract to optimize type checking
|
||||
* @see PrimeAmongSecondarySupertypes
|
||||
* @return this same instance
|
||||
*/
|
||||
@Override
|
||||
default HibernateProxy asHibernateProxy() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.security.PrivilegedAction;
|
|||
import java.util.Set;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
|
@ -105,7 +106,12 @@ public class ByteBuddyProxyFactory implements ProxyFactory, Serializable {
|
|||
public HibernateProxy run() {
|
||||
|
||||
try {
|
||||
return (HibernateProxy) proxyClass.getConstructor().newInstance();
|
||||
PrimeAmongSecondarySupertypes instance = (PrimeAmongSecondarySupertypes) proxyClass.getConstructor().newInstance();
|
||||
final HibernateProxy hibernateProxy = instance.asHibernateProxy();
|
||||
if ( hibernateProxy == null ) {
|
||||
throw new HibernateException( "Produced proxy does not correctly implement HibernateProxy" );
|
||||
}
|
||||
return hibernateProxy;
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
String logMessage = LOG.bytecodeEnhancementFailedBecauseOfDefaultConstructor( entityName );
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
*/
|
||||
package org.hibernate.proxy.pojo.bytebuddy;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.anyOf;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
@ -19,6 +23,15 @@ import java.util.function.Function;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.bytecode.internal.bytebuddy.ByteBuddyState;
|
||||
import org.hibernate.engine.spi.CompositeOwner;
|
||||
import org.hibernate.engine.spi.CompositeTracker;
|
||||
import org.hibernate.engine.spi.Managed;
|
||||
import org.hibernate.engine.spi.ManagedComposite;
|
||||
import org.hibernate.engine.spi.ManagedEntity;
|
||||
import org.hibernate.engine.spi.ManagedMappedSuperclass;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||
import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes;
|
||||
import org.hibernate.engine.spi.SelfDirtinessTracker;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
@ -33,6 +46,7 @@ import net.bytebuddy.description.type.TypeDescription;
|
|||
import net.bytebuddy.description.type.TypeList;
|
||||
import net.bytebuddy.dynamic.DynamicType;
|
||||
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
|
||||
import net.bytebuddy.implementation.DefaultMethodCall;
|
||||
import net.bytebuddy.implementation.SuperMethodCall;
|
||||
import net.bytebuddy.pool.TypePool;
|
||||
|
||||
|
@ -92,7 +106,25 @@ public class ByteBuddyProxyHelper implements Serializable {
|
|||
.intercept( SuperMethodCall.INSTANCE )
|
||||
.defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE )
|
||||
.implement( ProxyConfiguration.class )
|
||||
.intercept( helpers.getInterceptorFieldAccessor() );
|
||||
.intercept( helpers.getInterceptorFieldAccessor() )
|
||||
.ignoreAlso( isDeclaredBy( ManagedEntity.class ).and( named( "asManagedEntity" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asManagedEntity" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PersistentAttributeInterceptable.class ).and( named( "asPersistentAttributeInterceptable" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asPersistentAttributeInterceptable" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( SelfDirtinessTracker.class ).and( named( "asSelfDirtinessTracker" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asSelfDirtinessTracker" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( Managed.class ).and( named( "asManaged" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asManaged" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( ManagedComposite.class ).and( named( "asManagedComposite" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asManagedComposite" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( ManagedMappedSuperclass.class ).and( named( "asManagedMappedSuperclass" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asManagedMappedSuperclass" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( CompositeOwner.class ).and( named( "asCompositeOwner" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asCompositeOwner" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( CompositeTracker.class ).and( named( "asCompositeTracker" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asCompositeTracker" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( HibernateProxy.class ).and( named( "asHibernateProxy" ) ) )
|
||||
.ignoreAlso( isDeclaredBy( PrimeAmongSecondarySupertypes.class ).and( named( "asHibernateProxy" ) ) );
|
||||
}
|
||||
|
||||
public HibernateProxy deserializeProxy(SerializableProxy serializableProxy) {
|
||||
|
@ -114,7 +146,7 @@ public class ByteBuddyProxyHelper implements Serializable {
|
|||
serializableProxy.getPersistentClass(),
|
||||
serializableProxy.getInterfaces()
|
||||
);
|
||||
final HibernateProxy proxy = (HibernateProxy) proxyClass.newInstance();
|
||||
final HibernateProxy proxy = asHibernateProxy( proxyClass.newInstance() );
|
||||
( (ProxyConfiguration) proxy ).$$_hibernate_set_interceptor( interceptor );
|
||||
return proxy;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
|
|||
import org.hibernate.metamodel.spi.ValueAccess;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AbstractFetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.AssemblerCreationState;
|
||||
|
@ -196,7 +197,8 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
if ( compositeInstance != NULL_MARKER ) {
|
||||
notifyResolutionListeners( compositeInstance );
|
||||
|
||||
if ( compositeInstance instanceof HibernateProxy ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( compositeInstance );
|
||||
if ( lazyInitializer != null ) {
|
||||
final Initializer parentInitializer = processingState.resolveInitializer( navigablePath.getParent() );
|
||||
if ( parentInitializer != this ) {
|
||||
( (FetchParentAccess) parentInitializer ).registerResolutionListener( (entity) -> {
|
||||
|
@ -215,7 +217,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
.getInstantiator()
|
||||
.instantiate( this, sessionFactory);
|
||||
stateInjected = true;
|
||||
( (HibernateProxy) compositeInstance ).getHibernateLazyInitializer().setImplementation( target );
|
||||
lazyInitializer.setImplementation( target );
|
||||
}
|
||||
}
|
||||
else if ( stateAllNull == FALSE && stateInjected != TRUE ) {
|
||||
|
|
|
@ -648,9 +648,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
|
||||
final SharedSessionContractImplementor session = rowProcessingState.getJdbcValuesSourceProcessingState().getSession();
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
if ( entityInstance instanceof HibernateProxy ) {
|
||||
LazyInitializer hibernateLazyInitializer = ( (HibernateProxy) entityInstance ).getHibernateLazyInitializer();
|
||||
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entityInstance );
|
||||
if ( lazyInitializer != null ) {
|
||||
Object instance = persistenceContext.getEntity( entityKey );
|
||||
if ( instance == null ) {
|
||||
instance = resolveInstance(
|
||||
|
@ -662,7 +661,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
initializeEntity( instance, rowProcessingState, session, persistenceContext );
|
||||
}
|
||||
|
||||
hibernateLazyInitializer.setImplementation( instance );
|
||||
lazyInitializer.setImplementation( instance );
|
||||
entityInstanceForNotify = instance;
|
||||
}
|
||||
else {
|
||||
|
@ -865,10 +864,11 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
isReallyReadOnly = true;
|
||||
}
|
||||
else {
|
||||
if ( entityInstance instanceof HibernateProxy) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entityInstance );
|
||||
if ( lazyInitializer != null ) {
|
||||
// there is already a proxy for this impl
|
||||
// only set the status to read-only if the proxy is read-only
|
||||
isReallyReadOnly = ( (HibernateProxy) entityInstance ).getHibernateLazyInitializer().isReadOnly();
|
||||
isReallyReadOnly = lazyInitializer.isReadOnly();
|
||||
}
|
||||
}
|
||||
if ( isReallyReadOnly ) {
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.UniqueKeyLoadable;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.results.graph.AbstractFetchParentAccess;
|
||||
import org.hibernate.sql.results.graph.DomainResultAssembler;
|
||||
|
@ -168,9 +169,9 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
|
|||
);
|
||||
}
|
||||
|
||||
if ( entityInstance instanceof HibernateProxy ) {
|
||||
( (HibernateProxy) entityInstance ).getHibernateLazyInitializer()
|
||||
.setUnwrap( referencedModelPart.isUnwrapProxy() && concreteDescriptor.isInstrumented() );
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entityInstance );
|
||||
if ( lazyInitializer != null ) {
|
||||
lazyInitializer.setUnwrap( referencedModelPart.isUnwrapProxy() && concreteDescriptor.isInstrumented() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.metamodel.mapping.ModelPart;
|
|||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.spi.EntityIdentifierNavigablePath;
|
||||
import org.hibernate.sql.results.graph.AbstractFetchParentAccess;
|
||||
|
@ -216,8 +217,9 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
|||
}
|
||||
|
||||
final boolean unwrapProxy = toOneMapping.isUnwrapProxy() && isEnhancedForLazyLoading;
|
||||
if ( entityInstance instanceof HibernateProxy ) {
|
||||
( (HibernateProxy) entityInstance ).getHibernateLazyInitializer().setUnwrap( unwrapProxy );
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entityInstance );
|
||||
if ( lazyInitializer != null ) {
|
||||
lazyInitializer.setUnwrap( unwrapProxy );
|
||||
}
|
||||
isInitialized = true;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.hibernate.metamodel.model.domain.NavigableRole;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.persister.entity.UniqueKeyLoadable;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
|
@ -275,12 +276,13 @@ public class CircularBiDirectionalFetchImpl implements BiDirectionalFetch, Assoc
|
|||
initializer.resolveInstance( rowProcessingState );
|
||||
}
|
||||
final Object initializedInstance = initializer.getInitializedInstance();
|
||||
if ( initializedInstance instanceof HibernateProxy ) {
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( initializedInstance );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( initializedInstance.getClass().isAssignableFrom( javaType.getJavaTypeClass() ) ) {
|
||||
return initializedInstance;
|
||||
}
|
||||
initializer.initializeInstance( rowProcessingState );
|
||||
return ( (HibernateProxy) initializedInstance ).getHibernateLazyInitializer().getImplementation();
|
||||
return lazyInitializer.getImplementation();
|
||||
}
|
||||
return initializedInstance;
|
||||
}
|
||||
|
|
|
@ -155,12 +155,12 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT
|
|||
|
||||
// this code is largely copied from Session's bestGuessEntityName
|
||||
Object entity = object;
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
final LazyInitializer initializer = ( (HibernateProxy) entity ).getHibernateLazyInitializer();
|
||||
if ( initializer.isUninitialized() ) {
|
||||
entityName = initializer.getEntityName();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( entity );
|
||||
if ( lazyInitializer != null ) {
|
||||
if ( lazyInitializer.isUninitialized() ) {
|
||||
entityName = lazyInitializer.getEntityName();
|
||||
}
|
||||
entity = initializer.getImplementation();
|
||||
entity = lazyInitializer.getImplementation();
|
||||
}
|
||||
|
||||
if ( entityName == null ) {
|
||||
|
|
|
@ -91,8 +91,8 @@ public abstract class CollectionType extends AbstractType implements Association
|
|||
while ( elems.hasNext() ) {
|
||||
Object element = elems.next();
|
||||
// worrying about proxies is perhaps a little bit of overkill here...
|
||||
if ( element instanceof HibernateProxy ) {
|
||||
LazyInitializer li = ( (HibernateProxy) element ).getHibernateLazyInitializer();
|
||||
final LazyInitializer li = HibernateProxy.extractLazyInitializer( element );
|
||||
if ( li != null ) {
|
||||
if ( !li.isUninitialized() ) {
|
||||
element = li.getImplementation();
|
||||
}
|
||||
|
|
|
@ -24,8 +24,12 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.Joinable;
|
||||
import org.hibernate.persister.entity.UniqueKeyLoadable;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
|
||||
/**
|
||||
* Base for types which map associations to persistent entities.
|
||||
*
|
||||
|
@ -320,8 +324,9 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
}
|
||||
|
||||
final Object id;
|
||||
if ( x instanceof HibernateProxy ) {
|
||||
id = ( (HibernateProxy) x ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( x );
|
||||
if ( lazyInitializer != null ) {
|
||||
id = lazyInitializer.getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
final Class<?> mappedClass = persister.getMappedClass();
|
||||
|
@ -349,9 +354,9 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
|
||||
final Class<?> mappedClass = persister.getMappedClass();
|
||||
Object xid;
|
||||
if ( x instanceof HibernateProxy ) {
|
||||
xid = ( (HibernateProxy) x ).getHibernateLazyInitializer()
|
||||
.getInternalIdentifier();
|
||||
final LazyInitializer lazyInitializerX = HibernateProxy.extractLazyInitializer( x );
|
||||
if ( lazyInitializerX != null ) {
|
||||
xid = lazyInitializerX.getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
if ( mappedClass.isAssignableFrom( x.getClass() ) ) {
|
||||
|
@ -364,9 +369,9 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
}
|
||||
|
||||
Object yid;
|
||||
if ( y instanceof HibernateProxy ) {
|
||||
yid = ( (HibernateProxy) y ).getHibernateLazyInitializer()
|
||||
.getInternalIdentifier();
|
||||
final LazyInitializer lazyInitializerY = HibernateProxy.extractLazyInitializer( y );
|
||||
if ( lazyInitializerY != null ) {
|
||||
yid = lazyInitializerY.getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
if ( mappedClass.isAssignableFrom( y.getClass() ) ) {
|
||||
|
@ -505,8 +510,8 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
|
||||
if ( persister.hasIdentifierProperty() ) {
|
||||
final Object id;
|
||||
if ( value instanceof HibernateProxy ) {
|
||||
HibernateProxy proxy = (HibernateProxy) value;
|
||||
if ( isHibernateProxy( value ) ) {
|
||||
HibernateProxy proxy = asHibernateProxy( value );
|
||||
id = proxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
|
@ -652,9 +657,9 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
isNullable()
|
||||
);
|
||||
|
||||
if ( proxyOrEntity instanceof HibernateProxy ) {
|
||||
( (HibernateProxy) proxyOrEntity ).getHibernateLazyInitializer()
|
||||
.setUnwrap( isProxyUnwrapEnabled );
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( proxyOrEntity );
|
||||
if ( lazyInitializer != null ) {
|
||||
lazyInitializer.setUnwrap( isProxyUnwrapEnabled );
|
||||
}
|
||||
|
||||
return proxyOrEntity;
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.bytecode.internal.bytebuddy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hibernate.LazyInitializationException;
|
||||
import org.hibernate.engine.spi.PrimeAmongSecondarySupertypes;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.ProxyFactory;
|
||||
import org.hibernate.proxy.pojo.bytebuddy.ByteBuddyProxyFactory;
|
||||
import org.hibernate.proxy.pojo.bytebuddy.ByteBuddyProxyHelper;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
* Verifies that proxies being generated by ByteBuddyProxyHelper
|
||||
* do not break the contract with PrimeAmongSecondarySupertypes.
|
||||
* A problem in this are could obviously manifest as a semantic
|
||||
* issue, but could also manifest solely as a performance issue;
|
||||
* therefore we check implementation details via unit tests
|
||||
* rather than the typical integration test we'd have in such cases.
|
||||
*
|
||||
* @author Sanne Grinovero
|
||||
*/
|
||||
@TestForIssue( jiraKey = "HHH-15790" )
|
||||
public class SuperTypesEnhancementTest {
|
||||
|
||||
private static final ByteBuddyProxyHelper helper = new ByteBuddyProxyHelper( new ByteBuddyState() );
|
||||
|
||||
private static Stream<Arguments> superTypeMethods() {
|
||||
return Arrays.stream( PrimeAmongSecondarySupertypes.class.getDeclaredMethods() ).map( e -> Arguments.of( e ) );
|
||||
}
|
||||
|
||||
private static Stream<Arguments> interfaces() {
|
||||
return Arrays.stream( PrimeAmongSecondarySupertypes.class.getDeclaredMethods() ).map( m -> m.getReturnType() ).map( e -> Arguments.of( e ) );
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("superTypeMethods")
|
||||
public void testNamingConventions(Method m) {
|
||||
final Class<?> returnType = m.getReturnType();
|
||||
final String expectedMethodName = "as" + returnType.getSimpleName();
|
||||
Assert.assertEquals( expectedMethodName, m.getName() );
|
||||
Assert.assertNotNull( m.isDefault() );
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("superTypeMethods")
|
||||
public void testSubInterfaceOverrides(Method m) throws NoSuchMethodException {
|
||||
final Class<?> returnType = m.getReturnType();
|
||||
final Method subMethod = returnType.getMethod( m.getName(), m.getParameterTypes() );
|
||||
Assert.assertNotNull( subMethod );
|
||||
Assert.assertNotNull( subMethod.isDefault() );
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("interfaces")
|
||||
public void testAllProxyGeneration(Class<?> secondarySuper) {
|
||||
ProxyFactory enhancer = createProxyFactory( SampleClass.class, secondarySuper );
|
||||
final Object proxy = enhancer.getProxy( Integer.valueOf( 1 ), null );
|
||||
Assert.assertTrue( secondarySuper.isAssignableFrom( proxy.getClass() ) );
|
||||
PrimeAmongSecondarySupertypes casted = (PrimeAmongSecondarySupertypes) proxy;
|
||||
testForLIE( (SampleClass) proxy );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneratedHibernateProxy() {
|
||||
ProxyFactory enhancer = createProxyFactory( SampleClass.class, HibernateProxy.class );
|
||||
final Object proxy = enhancer.getProxy( Integer.valueOf( 1 ), null );
|
||||
Assert.assertTrue( HibernateProxy.class.isAssignableFrom( proxy.getClass() ) );
|
||||
Assert.assertTrue( proxy instanceof HibernateProxy );
|
||||
PrimeAmongSecondarySupertypes casted = (PrimeAmongSecondarySupertypes) proxy;
|
||||
final HibernateProxy extracted = casted.asHibernateProxy();
|
||||
Assert.assertNotNull( extracted );
|
||||
Assert.assertSame( proxy, extracted );
|
||||
testForLIE( (SampleClass) proxy );
|
||||
}
|
||||
|
||||
/**
|
||||
* Self-check: verify that this is in fact a lazy proxy
|
||||
*/
|
||||
private void testForLIE(SampleClass sampleProxy) {
|
||||
SampleClass other = new SampleClass();
|
||||
Assert.assertEquals( 7, other.additionMethod( 3,4 ) );
|
||||
Assert.assertThrows( LazyInitializationException.class, () -> sampleProxy.additionMethod( 3, 4 ) );
|
||||
}
|
||||
|
||||
private ProxyFactory createProxyFactory(Class<?> persistentClass, Class<?>... interfaces) {
|
||||
ByteBuddyProxyFactory proxyFactory = new ByteBuddyProxyFactory( helper );
|
||||
proxyFactory.postInstantiate( "", persistentClass, Set.of( interfaces ), null, null, null );
|
||||
return proxyFactory;
|
||||
}
|
||||
|
||||
//Just a class with some fields and methods to proxy
|
||||
static class SampleClass {
|
||||
int intField;
|
||||
String stringField;
|
||||
|
||||
public int additionMethod(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -20,6 +20,9 @@ import org.hibernate.envers.internal.tools.EntityTools;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
|
||||
/**
|
||||
* Base class for all Envers event listeners
|
||||
*
|
||||
|
@ -92,8 +95,8 @@ public abstract class BaseEnversEventListener implements EnversListener {
|
|||
String toEntityName;
|
||||
Object id;
|
||||
|
||||
if ( value instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) value;
|
||||
if ( isHibernateProxy( value ) ) {
|
||||
final HibernateProxy hibernateProxy = asHibernateProxy( value );
|
||||
id = hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||
// We've got to initialize the object from the proxy to later read its state.
|
||||
value = EntityTools.getTargetFromProxy( session.getFactory(), hibernateProxy );
|
||||
|
|
|
@ -19,6 +19,9 @@ import org.hibernate.envers.internal.tools.ReflectionTools;
|
|||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
|
||||
/**
|
||||
* @author Adam Warski (adam at warski dot org)
|
||||
* @author Hernán Chanfreau
|
||||
|
@ -105,8 +108,8 @@ public class EntityInstantiator {
|
|||
final Map originalId = (Map) versionsEntity.get( enversService.getConfig().getOriginalIdPropertyName() );
|
||||
for ( Object key : originalId.keySet() ) {
|
||||
final Object value = originalId.get( key );
|
||||
if ( value instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) value;
|
||||
if ( isHibernateProxy( value ) ) {
|
||||
final HibernateProxy hibernateProxy = asHibernateProxy( value );
|
||||
final LazyInitializer initializer = hibernateProxy.getHibernateLazyInitializer();
|
||||
final String entityName = initializer.getEntityName();
|
||||
final Object entityId = initializer.getInternalIdentifier();
|
||||
|
|
|
@ -15,6 +15,9 @@ import org.hibernate.envers.internal.entities.PropertyData;
|
|||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
|
||||
/**
|
||||
* An implementation of an identifier mapper for a single basic attribute property.
|
||||
*
|
||||
|
@ -77,8 +80,8 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu
|
|||
return null;
|
||||
}
|
||||
|
||||
if ( data instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) data;
|
||||
if ( isHibernateProxy( data ) ) {
|
||||
final HibernateProxy hibernateProxy = asHibernateProxy( data );
|
||||
return hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
|
@ -99,8 +102,8 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu
|
|||
data.put( propertyData.getName(), null );
|
||||
}
|
||||
else {
|
||||
if ( obj instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) obj;
|
||||
if ( isHibernateProxy( obj ) ) {
|
||||
final HibernateProxy hibernateProxy = asHibernateProxy( obj );
|
||||
data.put( propertyData.getName(), hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier() );
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -20,6 +20,9 @@ import org.hibernate.proxy.HibernateProxy;
|
|||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
|
||||
/**
|
||||
* An extension to the {@link SingleIdMapper} implementation that supports the use case of an {@code @IdClass}
|
||||
* mapping that contains an entity association where the {@code @IdClass} stores the primary key of the
|
||||
|
@ -130,8 +133,8 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper {
|
|||
data.put( propertyData.getName(), null );
|
||||
}
|
||||
else {
|
||||
if ( obj instanceof HibernateProxy ) {
|
||||
final HibernateProxy proxy = (HibernateProxy) obj;
|
||||
if ( isHibernateProxy( obj ) ) {
|
||||
final HibernateProxy proxy = asHibernateProxy( obj );
|
||||
data.put( propertyData.getName(), proxy.getHibernateLazyInitializer().getInternalIdentifier() );
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -15,6 +15,9 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
|
||||
/**
|
||||
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||
*/
|
||||
|
@ -31,8 +34,8 @@ public abstract class EntityTools {
|
|||
return null;
|
||||
}
|
||||
|
||||
if ( obj instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) obj;
|
||||
if ( isHibernateProxy( obj ) ) {
|
||||
final HibernateProxy hibernateProxy = asHibernateProxy( obj );
|
||||
return hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ import org.hibernate.proxy.HibernateProxy;
|
|||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.asHibernateProxy;
|
||||
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
|
||||
|
||||
/**
|
||||
* @author Tomasz Bech
|
||||
*/
|
||||
|
@ -114,10 +117,9 @@ public class RelationNotAuditedTarget extends BaseEnversJPAFunctionalTestCase {
|
|||
}
|
||||
|
||||
static Class<?> getClassWithoutInitializingProxy(Object object) {
|
||||
if (object instanceof HibernateProxy) {
|
||||
HibernateProxy proxy = (HibernateProxy) object;
|
||||
LazyInitializer li = proxy.getHibernateLazyInitializer();
|
||||
return li.getPersistentClass();
|
||||
final LazyInitializer lazyInitializer = HibernateProxy.extractLazyInitializer( object );
|
||||
if ( lazyInitializer != null ) {
|
||||
return lazyInitializer.getPersistentClass();
|
||||
}
|
||||
else {
|
||||
return object.getClass();
|
||||
|
|
Loading…
Reference in New Issue