HHH-14608 Merge causes StackOverflow when JPA proxy compliance is enabled
(cherry picked from commit 8b02aaf5a8
)
This commit is contained in:
parent
4783ef11f0
commit
8c66c83ef0
|
@ -614,7 +614,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) {
|
||||
if ( li.getSession() != this.getSession() ) {
|
||||
final EntityPersister persister = session.getFactory().getMetamodel().entityPersister( li.getEntityName() );
|
||||
final EntityKey key = session.generateEntityKey( li.getIdentifier(), persister );
|
||||
final EntityKey key = session.generateEntityKey( li.getInternalIdentifier(), persister );
|
||||
// any earlier proxy takes precedence
|
||||
proxiesByKey.putIfAbsent( key, proxy );
|
||||
proxy.getHibernateLazyInitializer().setSession( session );
|
||||
|
@ -1254,7 +1254,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
);
|
||||
}
|
||||
if ( found ) {
|
||||
return proxy.getHibernateLazyInitializer().getIdentifier();
|
||||
return proxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class DefaultEvictEventListener implements EvictEventListener {
|
|||
|
||||
if ( object instanceof HibernateProxy ) {
|
||||
final LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||
final Serializable id = li.getIdentifier();
|
||||
final Serializable id = li.getInternalIdentifier();
|
||||
if ( id == null ) {
|
||||
throw new IllegalArgumentException( "Could not determine identifier of proxy passed to evict()" );
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
|
|||
LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
LOG.trace( "Ignoring uninitialized proxy" );
|
||||
event.setResult( source.load( li.getEntityName(), li.getIdentifier() ) );
|
||||
event.setResult( source.load( li.getEntityName(), li.getInternalIdentifier() ) );
|
||||
//EARLY EXIT!
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1739,7 +1739,7 @@ public final class SessionImpl
|
|||
if ( li.getSession() != this ) {
|
||||
throw new TransientObjectException( "The proxy was not associated with this session" );
|
||||
}
|
||||
return li.getIdentifier();
|
||||
return li.getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
EntityEntry entry = persistenceContext.getEntry( object );
|
||||
|
@ -1767,7 +1767,7 @@ public final class SessionImpl
|
|||
}
|
||||
|
||||
private Serializable getProxyIdentifier(Object proxy) {
|
||||
return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getIdentifier();
|
||||
return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
|
||||
private FilterQueryPlan getFilterQueryPlan(
|
||||
|
|
|
@ -68,7 +68,7 @@ public class PersistenceUnitUtilImpl implements PersistenceUnitUtil, Serializabl
|
|||
}
|
||||
|
||||
if ( entity instanceof HibernateProxy ) {
|
||||
return ((HibernateProxy) entity).getHibernateLazyInitializer().getIdentifier();
|
||||
return ((HibernateProxy) entity).getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
else if ( entity instanceof ManagedEntity ) {
|
||||
EntityEntry entityEntry = ((ManagedEntity) entity).$$_hibernate_getEntityEntry();
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.SessionException;
|
|||
import org.hibernate.TransientObjectException;
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
|
@ -83,6 +84,11 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
return entityName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Serializable getInternalIdentifier() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Serializable getIdentifier() {
|
||||
if ( isUninitialized() && isInitializeProxyWhenAccessingIdentifier() ) {
|
||||
|
@ -92,7 +98,7 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
}
|
||||
|
||||
private boolean isInitializeProxyWhenAccessingIdentifier() {
|
||||
return session != null && session.getFactory()
|
||||
return getSession() != null && getSession().getFactory()
|
||||
.getSessionFactoryOptions()
|
||||
.getJpaCompliance().isJpaProxyComplianceEnabled();
|
||||
}
|
||||
|
@ -252,7 +258,7 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
public final void initializeWithoutLoadIfPossible() {
|
||||
if ( !initialized && session != null && session.isOpen() ) {
|
||||
final EntityKey key = session.generateEntityKey(
|
||||
getIdentifier(),
|
||||
getInternalIdentifier(),
|
||||
session.getFactory().getMetamodel().entityPersister( getEntityName() )
|
||||
);
|
||||
final Object entity = session.getPersistenceContext().getEntity( key );
|
||||
|
@ -297,7 +303,7 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
}
|
||||
|
||||
private Object getProxyOrNull() {
|
||||
final EntityKey entityKey = generateEntityKeyOrNull( getIdentifier(), session, getEntityName() );
|
||||
final EntityKey entityKey = generateEntityKeyOrNull( getInternalIdentifier(), session, getEntityName() );
|
||||
if ( entityKey != null && session != null && session.isOpen() ) {
|
||||
return session.getPersistenceContext().getProxy( entityKey );
|
||||
}
|
||||
|
@ -318,8 +324,8 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
|
||||
@Override
|
||||
public final Object getImplementation(SharedSessionContractImplementor s) throws HibernateException {
|
||||
final EntityKey entityKey = generateEntityKeyOrNull( getIdentifier(), s, getEntityName() );
|
||||
return (entityKey == null ? null : s.getPersistenceContext().getEntity( entityKey ));
|
||||
final EntityKey entityKey = generateEntityKeyOrNull( getInternalIdentifier(), s, getEntityName() );
|
||||
return ( entityKey == null ? null : s.getPersistenceContext().getEntity( entityKey ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -368,9 +374,10 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
|
|||
}
|
||||
this.readOnly = readOnly;
|
||||
if ( initialized ) {
|
||||
EntityKey key = generateEntityKeyOrNull( getIdentifier(), session, getEntityName() );
|
||||
if ( key != null && session.getPersistenceContext().containsEntity( key ) ) {
|
||||
session.getPersistenceContext().setReadOnly( target, readOnly );
|
||||
EntityKey key = generateEntityKeyOrNull( getInternalIdentifier(), session, getEntityName() );
|
||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||
if ( key != null && persistenceContext.containsEntity( key ) ) {
|
||||
persistenceContext.setReadOnly( target, readOnly );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,17 @@ public interface LazyInitializer {
|
|||
*
|
||||
* @return The identifier value.
|
||||
*/
|
||||
default Serializable getInternalIdentifier() {
|
||||
return getIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the identifier value for the entity our owning proxy represents.
|
||||
*
|
||||
* When JPA proxy compliance is enabled the proxy is initialized.
|
||||
*
|
||||
* @return The identifier value.
|
||||
*/
|
||||
Serializable getIdentifier();
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,7 +116,7 @@ public class MapProxy implements HibernateProxy, Map, Serializable {
|
|||
private Object serializableProxy() {
|
||||
return new SerializableMapProxy(
|
||||
li.getEntityName(),
|
||||
li.getIdentifier(),
|
||||
li.getInternalIdentifier(),
|
||||
( li.isReadOnlySettingAvailable() ? Boolean.valueOf( li.isReadOnly() ) : li.isReadOnlyBeforeAttachedToSession() ),
|
||||
li.getSessionFactoryUuid(),
|
||||
li.isAllowLoadOutsideTransaction()
|
||||
|
|
|
@ -85,7 +85,7 @@ public class ByteBuddyInterceptor extends BasicLazyInitializer implements ProxyC
|
|||
getEntityName(),
|
||||
persistentClass,
|
||||
interfaces,
|
||||
getIdentifier(),
|
||||
getInternalIdentifier(),
|
||||
( isReadOnlySettingAvailable() ? Boolean.valueOf( isReadOnly() ) : isReadOnlyBeforeAttachedToSession() ),
|
||||
getSessionFactoryUuid(),
|
||||
isAllowLoadOutsideTransaction(),
|
||||
|
|
|
@ -123,7 +123,7 @@ public class JavassistLazyInitializer extends BasicLazyInitializer implements Me
|
|||
getEntityName(),
|
||||
persistentClass,
|
||||
interfaces,
|
||||
getIdentifier(),
|
||||
getInternalIdentifier(),
|
||||
( isReadOnlySettingAvailable() ? Boolean.valueOf( isReadOnly() ) : isReadOnlyBeforeAttachedToSession() ),
|
||||
getSessionFactoryUuid(),
|
||||
isAllowLoadOutsideTransaction(),
|
||||
|
|
|
@ -208,7 +208,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
id = entity;
|
||||
}
|
||||
else if ( HibernateProxy.class.isInstance( entity ) ) {
|
||||
id = ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
||||
id = ( (HibernateProxy) entity ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
if ( idGetter == null ) {
|
||||
|
@ -432,7 +432,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
|
||||
if ( HibernateProxy.class.isInstance( entity ) ) {
|
||||
// entity is a proxy, so we know it is not transient; just return ID from proxy
|
||||
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
||||
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
|
||||
if ( session != null ) {
|
||||
|
|
|
@ -369,7 +369,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
|
||||
final Serializable id;
|
||||
if ( x instanceof HibernateProxy ) {
|
||||
id = ( (HibernateProxy) x ).getHibernateLazyInitializer().getIdentifier();
|
||||
id = ( (HibernateProxy) x ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
final Class mappedClass = persister.getMappedClass();
|
||||
|
@ -399,7 +399,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
Serializable xid;
|
||||
if ( x instanceof HibernateProxy ) {
|
||||
xid = ( (HibernateProxy) x ).getHibernateLazyInitializer()
|
||||
.getIdentifier();
|
||||
.getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
if ( mappedClass.isAssignableFrom( x.getClass() ) ) {
|
||||
|
@ -414,7 +414,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
Serializable yid;
|
||||
if ( y instanceof HibernateProxy ) {
|
||||
yid = ( (HibernateProxy) y ).getHibernateLazyInitializer()
|
||||
.getIdentifier();
|
||||
.getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
if ( mappedClass.isAssignableFrom( y.getClass() ) ) {
|
||||
|
@ -546,7 +546,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
final Serializable id;
|
||||
if ( value instanceof HibernateProxy ) {
|
||||
HibernateProxy proxy = (HibernateProxy) value;
|
||||
id = proxy.getHibernateLazyInitializer().getIdentifier();
|
||||
id = proxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
id = persister.getIdentifier( value );
|
||||
|
|
|
@ -94,7 +94,7 @@ public abstract class BaseEnversEventListener implements EnversListener {
|
|||
|
||||
if ( value instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) value;
|
||||
id = hibernateProxy.getHibernateLazyInitializer().getIdentifier();
|
||||
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 );
|
||||
// HHH-7249
|
||||
|
|
|
@ -111,7 +111,7 @@ public class EntityInstantiator {
|
|||
final HibernateProxy hibernateProxy = (HibernateProxy) value;
|
||||
final LazyInitializer initializer = hibernateProxy.getHibernateLazyInitializer();
|
||||
final String entityName = initializer.getEntityName();
|
||||
final Serializable entityId = initializer.getIdentifier();
|
||||
final Serializable entityId = initializer.getInternalIdentifier();
|
||||
if ( enversService.getEntitiesConfigurations().isVersioned( entityName ) ) {
|
||||
final String entityClassName = enversService.getEntitiesConfigurations().get( entityName ).getEntityClassName();
|
||||
final Class entityClass = ReflectionTools.loadClass(
|
||||
|
|
|
@ -88,7 +88,7 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu
|
|||
|
||||
if ( data instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) data;
|
||||
return hibernateProxy.getHibernateLazyInitializer().getIdentifier();
|
||||
return hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
return AccessController.doPrivileged(
|
||||
|
@ -122,7 +122,7 @@ public class SingleIdMapper extends AbstractIdMapper implements SimpleIdMapperBu
|
|||
else {
|
||||
if ( obj instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) obj;
|
||||
data.put( propertyData.getName(), hibernateProxy.getHibernateLazyInitializer().getIdentifier() );
|
||||
data.put( propertyData.getName(), hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier() );
|
||||
}
|
||||
else {
|
||||
final Object value = AccessController.doPrivileged(
|
||||
|
|
|
@ -113,7 +113,7 @@ public class VirtualEntitySingleIdMapper extends SingleIdMapper {
|
|||
else {
|
||||
if ( obj instanceof HibernateProxy ) {
|
||||
final HibernateProxy proxy = (HibernateProxy) obj;
|
||||
data.put( propertyData.getName(), proxy.getHibernateLazyInitializer().getIdentifier() );
|
||||
data.put( propertyData.getName(), proxy.getHibernateLazyInitializer().getInternalIdentifier() );
|
||||
}
|
||||
else {
|
||||
final Object value = AccessController.doPrivileged(
|
||||
|
|
|
@ -33,7 +33,7 @@ public abstract class EntityTools {
|
|||
|
||||
if ( obj instanceof HibernateProxy ) {
|
||||
final HibernateProxy hibernateProxy = (HibernateProxy) obj;
|
||||
return hibernateProxy.getHibernateLazyInitializer().getIdentifier();
|
||||
return hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
|
||||
return session.getEntityPersister( entityName, obj ).getIdentifier( obj, session );
|
||||
|
@ -51,7 +51,7 @@ public abstract class EntityTools {
|
|||
try {
|
||||
return tempSession.get(
|
||||
proxy.getHibernateLazyInitializer().getEntityName(),
|
||||
proxy.getHibernateLazyInitializer().getIdentifier()
|
||||
proxy.getHibernateLazyInitializer().getInternalIdentifier()
|
||||
);
|
||||
}
|
||||
finally {
|
||||
|
|
|
@ -80,7 +80,7 @@ public class RevisionsOfEntityQuery extends AbstractAuditQuery {
|
|||
Object revisionInfoObject = ( (Map) versionsEntity.get( originalId ) ).get( revisionPropertyName );
|
||||
|
||||
if ( revisionInfoObject instanceof HibernateProxy ) {
|
||||
return (Number) ( (HibernateProxy) revisionInfoObject ).getHibernateLazyInitializer().getIdentifier();
|
||||
return (Number) ( (HibernateProxy) revisionInfoObject ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||
}
|
||||
else {
|
||||
// Not a proxy - must be read from cache or with a join
|
||||
|
|
|
@ -114,8 +114,8 @@ public class ProxyIdentifier extends BaseEnversJPAFunctionalTestCase {
|
|||
LazyInitializer lazyInitializer = proxyCreateByEnvers.getHibernateLazyInitializer();
|
||||
|
||||
Assert.assertTrue( lazyInitializer.isUninitialized() );
|
||||
Assert.assertNotNull( lazyInitializer.getIdentifier() );
|
||||
Assert.assertEquals( tnae1.getId(), lazyInitializer.getIdentifier() );
|
||||
Assert.assertNotNull( lazyInitializer.getInternalIdentifier() );
|
||||
Assert.assertEquals( tnae1.getId(), lazyInitializer.getInternalIdentifier() );
|
||||
Assert.assertTrue( lazyInitializer.isUninitialized() );
|
||||
|
||||
Assert.assertEquals( uste1.getId(), rev1.getReference().getId() );
|
||||
|
|
Loading…
Reference in New Issue