From 2c39bc0ac620ac642360a8ec205a5d15612bec87 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Mon, 15 Mar 2021 16:42:21 +0000 Subject: [PATCH] HHH-14502 Iterations and memory retention improvements for processing of PropertyContainer metadata --- .../org/hibernate/cfg/AnnotationBinder.java | 3 +- .../org/hibernate/cfg/PropertyContainer.java | 39 ++++++++++++++----- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java index 46df157133..a1e0f7c779 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -1500,8 +1500,7 @@ public final class AnnotationBinder { MetadataBuildingContext context) { int idPropertyCounter = 0; - Collection properties = propertyContainer.getProperties(); - for ( XProperty p : properties ) { + for ( XProperty p : propertyContainer.propertyIterator() ) { final int currentIdPropertyCounter = addProperty( propertyContainer, p, diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/PropertyContainer.java b/hibernate-core/src/main/java/org/hibernate/cfg/PropertyContainer.java index 31004e0dd2..02e3e50b34 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/PropertyContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/PropertyContainer.java @@ -9,6 +9,7 @@ package org.hibernate.cfg; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -35,6 +36,7 @@ import org.hibernate.boot.jaxb.SourceType; import org.hibernate.cfg.annotations.HCANNHelper; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.CollectionHelper; import org.jboss.logging.Logger; @@ -63,7 +65,7 @@ class PropertyContainer { */ private final AccessType classLevelAccessType; - private final TreeMap persistentAttributeMap; + private final List persistentAttributes; PropertyContainer(XClass clazz, XClass entityAtStake, AccessType defaultClassLevelAccessType) { this.xClass = clazz; @@ -83,7 +85,6 @@ class PropertyContainer { : defaultClassLevelAccessType; assert classLevelAccessType == AccessType.FIELD || classLevelAccessType == AccessType.PROPERTY; - this.persistentAttributeMap = new TreeMap(); final List fields = xClass.getDeclaredProperties( AccessType.FIELD.getType() ); final List getters = xClass.getDeclaredProperties( AccessType.PROPERTY.getType() ); @@ -92,18 +93,23 @@ class PropertyContainer { final Map persistentAttributesFromGetters = new HashMap(); + final TreeMap localAttributeMap = new TreeMap<>(); collectPersistentAttributesUsingLocalAccessType( - persistentAttributeMap, + xClass, + localAttributeMap, persistentAttributesFromGetters, fields, getters ); collectPersistentAttributesUsingClassLevelAccessType( - persistentAttributeMap, + xClass, + classLevelAccessType, + localAttributeMap, persistentAttributesFromGetters, fields, getters ); + this.persistentAttributes = verifyAndInitializePersistentAttributes( xClass, localAttributeMap ); } private void preFilter(List fields, List getters) { @@ -124,7 +130,8 @@ class PropertyContainer { } } - private void collectPersistentAttributesUsingLocalAccessType( + private static void collectPersistentAttributesUsingLocalAccessType( + XClass xClass, TreeMap persistentAttributeMap, Map persistentAttributesFromGetters, List fields, @@ -176,7 +183,9 @@ class PropertyContainer { } } - private void collectPersistentAttributesUsingClassLevelAccessType( + private static void collectPersistentAttributesUsingClassLevelAccessType( + XClass xClass, + AccessType classLevelAccessType, TreeMap persistentAttributeMap, Map persistentAttributesFromGetters, List fields, @@ -229,20 +238,30 @@ class PropertyContainer { return classLevelAccessType; } + /** + * @deprecated Use the {@link #propertyIterator()} method instead. + */ + @Deprecated public Collection getProperties() { - assertTypesAreResolvable(); - return Collections.unmodifiableCollection( persistentAttributeMap.values() ); + return Collections.unmodifiableCollection( this.persistentAttributes ); } - private void assertTypesAreResolvable() { - for ( XProperty xProperty : persistentAttributeMap.values() ) { + public Iterable propertyIterator() { + return persistentAttributes; + } + + private static List verifyAndInitializePersistentAttributes(XClass xClass, Map localAttributeMap) { + ArrayList output = new ArrayList( localAttributeMap.size() ); + for ( XProperty xProperty : localAttributeMap.values() ) { if ( !xProperty.isTypeResolved() && !discoverTypeWithoutReflection( xProperty ) ) { String msg = "Property " + StringHelper.qualify( xClass.getName(), xProperty.getName() ) + " has an unbound type and no explicit target entity. Resolve this Generic usage issue" + " or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type"; throw new AnnotationException( msg ); } + output.add( xProperty ); } + return CollectionHelper.toSmallList( output ); } // // private void considerExplicitFieldAndPropertyAccess() {