HHH-15790 Make HibernateProxy also type-cache friendly

This commit is contained in:
Sanne Grinovero 2022-11-29 23:43:44 +00:00 committed by Sanne Grinovero
parent 366a1e9c1d
commit fbf469830c
44 changed files with 482 additions and 212 deletions

View File

@ -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();
}

View File

@ -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;

View File

@ -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()

View File

@ -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 );

View File

@ -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}

View File

@ -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<>();

View File

@ -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 ) {

View File

@ -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;
}
}

View File

@ -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 )

View File

@ -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 );

View File

@ -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();

View File

@ -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 ) ) {

View File

@ -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 {

View File

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

View File

@ -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();

View File

@ -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 );

View File

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

View File

@ -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();

View File

@ -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();
}
}

View File

@ -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 {

View File

@ -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();

View File

@ -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();

View File

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

View File

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

View File

@ -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 ) {

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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 );

View File

@ -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;
}

View File

@ -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 ) {

View File

@ -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 ) {

View File

@ -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() );
}
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 ) {

View File

@ -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();
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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 );

View File

@ -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&aacute;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();

View File

@ -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 {

View File

@ -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 {

View File

@ -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();
}

View File

@ -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();