ComponentTuplizer generates a LOT of proxy classes when using Bytebuddy as bytecode provider

Description

Due to the way Component#getType() is implemented, we generate a LOT of basic proxy classes for each entity.

On a simple test case, I got:

org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$ICqUNWPu org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$EC2O4yJT org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$nRNLTL4U org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$5vx4eOsS org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$1co089ET org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$06m9EwCM org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$413katnH org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$i4bM2pZs org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$ZRiNWpMf org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$izmxtKTJ org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$dpyg8Tzn org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$uQUoEvLx org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$j9VZdVub org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$IdssUNvJ org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$7E9Hjp6C org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$b1loGWpF org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$wA40QQ0q org.hibernate.bugs.entity.Person => org.hibernate.bugs.entity.Person$HibernateBasicProxy$oGdqmDO0
@Override public Type getType() throws MappingException { // TODO : temporary initial step towards HHH-1907 final ComponentMetamodel metamodel = new ComponentMetamodel( this, getMetadata().getMetadataBuildingOptions() ); final TypeFactory factory = getMetadata().getTypeConfiguration().getTypeResolver().getTypeFactory(); return isEmbedded() ? factory.embeddedComponent( metamodel ) : factory.component( metamodel ); }

The fact that we initialize the ComponentMetamodel for each getType() call generates a new basic proxy class for each call.

Moreover, the proxy is created for the entity class deep into the component (e.g. a property) stack trace and not shared for all the components of the entities.

Stack trace:

Thread [main] (Suspended (breakpoint at line 48 in BasicProxyFactoryImpl)) BasicProxyFactoryImpl.<init>(Class, Class[], ByteBuddyState) line: 48 ProxyFactoryFactoryImpl.buildBasicProxyFactory(Class, Class[]) line: 30 PojoComponentTuplizer$ProxiedInstantiator.<init>(Class) line: 164 PojoComponentTuplizer.buildInstantiator(Component) line: 127 PojoComponentTuplizer(AbstractComponentTuplizer).<init>(Component) line: 55 PojoComponentTuplizer.<init>(Component) line: 41 NativeConstructorAccessorImpl.newInstance0(Constructor<?>, Object[]) line: not available [native method] NativeConstructorAccessorImpl.newInstance(Object[]) line: 62 DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45 Constructor<T>.newInstance(Object...) line: 423 ComponentTuplizerFactory.constructTuplizer(Class<ComponentTuplizer>, Component) line: 104 ComponentTuplizerFactory.constructDefaultTuplizer(EntityMode, Component) line: 128 ComponentMetamodel.<init>(Component, ComponentTuplizerFactory) line: 77 ComponentMetamodel.<init>(Component, MetadataBuildingOptions) line: 52 Component.getType() line: 213 Component(SimpleValue).isValid(Mapping) line: 453 Property.isValid(Mapping) line: 226 RootClass(PersistentClass).validate(Mapping) line: 624 RootClass.validate(Mapping) line: 267 MetadataImpl.validate() line: 347 SessionFactoryBuilderImpl.build() line: 466 EntityManagerFactoryBuilderImpl.build() line: 939 HibernatePersistenceProvider.createEntityManagerFactory(String, Map) line: 56 Persistence.createEntityManagerFactory(String, Map) line: 79 Persistence.createEntityManagerFactory(String) line: 54 JPAUnitTestCase.init() line: 24 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43 Method.invoke(Object, Object...) line: 498 FrameworkMethod$1.runReflectiveCall() line: 50 FrameworkMethod$1(ReflectiveCallable).run() line: 12 FrameworkMethod.invokeExplosively(Object, Object...) line: 47 RunBefores.evaluate() line: 24 RunAfters.evaluate() line: 27 BlockJUnit4ClassRunner(ParentRunner<T>).runLeaf(Statement, Description, RunNotifier) line: 325 BlockJUnit4ClassRunner.runChild(FrameworkMethod, RunNotifier) line: 78 BlockJUnit4ClassRunner.runChild(Object, RunNotifier) line: 57 ParentRunner$3.run() line: 290 ParentRunner$1.schedule(Runnable) line: 71 BlockJUnit4ClassRunner(ParentRunner<T>).runChildren(RunNotifier) line: 288 ParentRunner<T>.access$000(ParentRunner, RunNotifier) line: 58 ParentRunner$2.evaluate() line: 268 BlockJUnit4ClassRunner(ParentRunner<T>).run(RunNotifier) line: 363 JUnit4TestReference.run(TestExecution) line: 86 TestExecution.run(ITestReference[]) line: 38 RemoteTestRunner.runTests(String[], String, TestExecution) line: 538 RemoteTestRunner.runTests(TestExecution) line: 760 RemoteTestRunner.run() line: 460 RemoteTestRunner.main(String[]) line: 206

Activity

Show:
Fixed

Details

Assignee

Reporter

Components

Fix versions

Priority

Created July 10, 2018 at 6:56 PM
Updated July 20, 2018 at 1:40 PM
Resolved July 19, 2018 at 8:07 AM

Flag notifications