HHH-17946 - Avoid creating ProxyFactory if possible
This commit is contained in:
parent
44aec90538
commit
f68f6aae50
|
@ -138,30 +138,60 @@ public class EntityRepresentationStrategyPojoStandard implements EntityRepresent
|
|||
identifierPropertyAccess = makePropertyAccess( identifierProperty );
|
||||
}
|
||||
|
||||
final BytecodeProvider bytecodeProvider =
|
||||
creationContext.getBootstrapContext().getServiceRegistry()
|
||||
.requireService( BytecodeProvider.class );
|
||||
this.strategySelector = creationContext.getServiceRegistry().getService( StrategySelector.class );
|
||||
|
||||
final BytecodeProvider bytecodeProvider = creationContext.getBootstrapContext().getServiceRegistry().requireService( BytecodeProvider.class );
|
||||
|
||||
this.proxyFactory = resolveProxyFactory(
|
||||
bootDescriptor,
|
||||
runtimeDescriptor,
|
||||
proxyJtd,
|
||||
bytecodeProvider,
|
||||
creationContext
|
||||
);
|
||||
|
||||
this.propertyAccessMap = buildPropertyAccessMap( bootDescriptor );
|
||||
this.reflectionOptimizer = resolveReflectionOptimizer( bytecodeProvider );
|
||||
|
||||
this.instantiator = determineInstantiator( bootDescriptor, runtimeDescriptor.getEntityMetamodel() );
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private ProxyFactory resolveProxyFactory(
|
||||
PersistentClass bootDescriptor,
|
||||
EntityPersister entityPersister,
|
||||
JavaType<?> proxyJtd,
|
||||
BytecodeProvider bytecodeProvider,
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
final EntityMetamodel entityMetamodel = entityPersister.getEntityMetamodel();
|
||||
final boolean enhancedForLazyLoading = entityPersister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
|
||||
|
||||
// todo : `@ConcreteProxy` handling
|
||||
if ( enhancedForLazyLoading
|
||||
&& bootDescriptor.getRootClass() == bootDescriptor
|
||||
&& !bootDescriptor.hasSubclasses() ) {
|
||||
// the entity is bytecode enhanced for lazy loading and is not part of an inheritance hierarchy,
|
||||
// so no need for a ProxyFactory
|
||||
return null;
|
||||
}
|
||||
|
||||
final EntityMetamodel entityMetamodel = runtimeDescriptor.getEntityMetamodel();
|
||||
ProxyFactory proxyFactory = null;
|
||||
if ( proxyJtd != null && entityMetamodel.isLazy() ) {
|
||||
proxyFactory = createProxyFactory( bootDescriptor, bytecodeProvider, creationContext );
|
||||
final ProxyFactory proxyFactory = createProxyFactory( bootDescriptor, bytecodeProvider, creationContext );
|
||||
if ( proxyFactory == null ) {
|
||||
entityMetamodel.setLazy( false );
|
||||
}
|
||||
return proxyFactory;
|
||||
}
|
||||
this.proxyFactory = proxyFactory;
|
||||
|
||||
// resolveReflectionOptimizer may lead to a makePropertyAccess call which requires strategySelector
|
||||
this.strategySelector = creationContext.getServiceRegistry().getService( StrategySelector.class );
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<String, PropertyAccess> buildPropertyAccessMap(PersistentClass bootDescriptor) {
|
||||
final Map<String, PropertyAccess> propertyAccessMap = new LinkedHashMap<>();
|
||||
for ( Property property : bootDescriptor.getPropertyClosure() ) {
|
||||
propertyAccessMap.put( property.getName(), makePropertyAccess( property ) );
|
||||
}
|
||||
this.propertyAccessMap = propertyAccessMap;
|
||||
this.reflectionOptimizer = resolveReflectionOptimizer( bytecodeProvider );
|
||||
|
||||
this.instantiator = determineInstantiator( bootDescriptor, entityMetamodel );
|
||||
return propertyAccessMap;
|
||||
}
|
||||
|
||||
private EntityInstantiator determineInstantiator(PersistentClass bootDescriptor, EntityMetamodel entityMetamodel) {
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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.orm.test.bytecode.enhancement.lazy.proxy;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.model.internal.ToOneBinder;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.metamodel.internal.EntityRepresentationStrategyPojoStandard;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.hibernate.testing.logger.LoggerInspectionRule;
|
||||
import org.hibernate.testing.logger.Triggerable;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for cases where we do not want a {@linkplain org.hibernate.proxy.ProxyFactory}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@RunWith(BytecodeEnhancerRunner.class )
|
||||
@EnhancementOptions(lazyLoading = true)
|
||||
public class NoProxyFactoryTests extends BaseNonConfigCoreFunctionalTestCase {
|
||||
@Rule
|
||||
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
|
||||
Logger.getMessageLogger( CoreMessageLogger.class, EntityRepresentationStrategyPojoStandard.class.getName() )
|
||||
);
|
||||
|
||||
/**
|
||||
* See org.hibernate.internal.CoreMessageLogger#unableToCreateProxyFactory
|
||||
*/
|
||||
private final Triggerable triggerable = logInspection.watchForLogMessages( "HHH000305" );
|
||||
|
||||
|
||||
@Override
|
||||
protected void applyMetadataSources(MetadataSources sources) {
|
||||
sources.addAnnotatedClasses( SimpleEntity.class );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoInheritance() {
|
||||
assertThat( triggerable.wasTriggered() )
|
||||
.describedAs( "Warning was logged" )
|
||||
.isFalse();
|
||||
|
||||
final MappingMetamodelImplementor mappingMetamodel = sessionFactory().getMappingMetamodel();
|
||||
final EntityPersister entityDescriptor = mappingMetamodel.findEntityDescriptor( SimpleEntity.class );
|
||||
assertThat( entityDescriptor.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ).isTrue();
|
||||
assertThat( entityDescriptor.getRepresentationStrategy().getProxyFactory() ).isNull();
|
||||
|
||||
inTransaction( (session) -> {
|
||||
final SimpleEntity reference = session.getReference( SimpleEntity.class, 1 );
|
||||
assertThat( Hibernate.isInitialized( reference ) ).isFalse();
|
||||
assertThat( reference ).isNotInstanceOf( HibernateProxy.class );
|
||||
} );
|
||||
}
|
||||
|
||||
@Entity(name="SimpleEntity")
|
||||
@Table(name="SimpleEntity")
|
||||
public static class SimpleEntity {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
public final Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public final void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public final void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue