HHH-14502 Iterations and memory retention improvements for processing of PropertyContainer metadata

This commit is contained in:
Sanne Grinovero 2021-03-15 16:42:21 +00:00
parent 9f22dafe17
commit 2c39bc0ac6
2 changed files with 30 additions and 12 deletions

View File

@ -1500,8 +1500,7 @@ public final class AnnotationBinder {
MetadataBuildingContext context) { MetadataBuildingContext context) {
int idPropertyCounter = 0; int idPropertyCounter = 0;
Collection<XProperty> properties = propertyContainer.getProperties(); for ( XProperty p : propertyContainer.propertyIterator() ) {
for ( XProperty p : properties ) {
final int currentIdPropertyCounter = addProperty( final int currentIdPropertyCounter = addProperty(
propertyContainer, propertyContainer,
p, p,

View File

@ -9,6 +9,7 @@
package org.hibernate.cfg; package org.hibernate.cfg;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -35,6 +36,7 @@ import org.hibernate.boot.jaxb.SourceType;
import org.hibernate.cfg.annotations.HCANNHelper; import org.hibernate.cfg.annotations.HCANNHelper;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -63,7 +65,7 @@ class PropertyContainer {
*/ */
private final AccessType classLevelAccessType; private final AccessType classLevelAccessType;
private final TreeMap<String, XProperty> persistentAttributeMap; private final List<XProperty> persistentAttributes;
PropertyContainer(XClass clazz, XClass entityAtStake, AccessType defaultClassLevelAccessType) { PropertyContainer(XClass clazz, XClass entityAtStake, AccessType defaultClassLevelAccessType) {
this.xClass = clazz; this.xClass = clazz;
@ -83,7 +85,6 @@ class PropertyContainer {
: defaultClassLevelAccessType; : defaultClassLevelAccessType;
assert classLevelAccessType == AccessType.FIELD || classLevelAccessType == AccessType.PROPERTY; assert classLevelAccessType == AccessType.FIELD || classLevelAccessType == AccessType.PROPERTY;
this.persistentAttributeMap = new TreeMap<String, XProperty>();
final List<XProperty> fields = xClass.getDeclaredProperties( AccessType.FIELD.getType() ); final List<XProperty> fields = xClass.getDeclaredProperties( AccessType.FIELD.getType() );
final List<XProperty> getters = xClass.getDeclaredProperties( AccessType.PROPERTY.getType() ); final List<XProperty> getters = xClass.getDeclaredProperties( AccessType.PROPERTY.getType() );
@ -92,18 +93,23 @@ class PropertyContainer {
final Map<String,XProperty> persistentAttributesFromGetters = new HashMap<String, XProperty>(); final Map<String,XProperty> persistentAttributesFromGetters = new HashMap<String, XProperty>();
final TreeMap<String, XProperty> localAttributeMap = new TreeMap<>();
collectPersistentAttributesUsingLocalAccessType( collectPersistentAttributesUsingLocalAccessType(
persistentAttributeMap, xClass,
localAttributeMap,
persistentAttributesFromGetters, persistentAttributesFromGetters,
fields, fields,
getters getters
); );
collectPersistentAttributesUsingClassLevelAccessType( collectPersistentAttributesUsingClassLevelAccessType(
persistentAttributeMap, xClass,
classLevelAccessType,
localAttributeMap,
persistentAttributesFromGetters, persistentAttributesFromGetters,
fields, fields,
getters getters
); );
this.persistentAttributes = verifyAndInitializePersistentAttributes( xClass, localAttributeMap );
} }
private void preFilter(List<XProperty> fields, List<XProperty> getters) { private void preFilter(List<XProperty> fields, List<XProperty> getters) {
@ -124,7 +130,8 @@ class PropertyContainer {
} }
} }
private void collectPersistentAttributesUsingLocalAccessType( private static void collectPersistentAttributesUsingLocalAccessType(
XClass xClass,
TreeMap<String, XProperty> persistentAttributeMap, TreeMap<String, XProperty> persistentAttributeMap,
Map<String,XProperty> persistentAttributesFromGetters, Map<String,XProperty> persistentAttributesFromGetters,
List<XProperty> fields, List<XProperty> fields,
@ -176,7 +183,9 @@ class PropertyContainer {
} }
} }
private void collectPersistentAttributesUsingClassLevelAccessType( private static void collectPersistentAttributesUsingClassLevelAccessType(
XClass xClass,
AccessType classLevelAccessType,
TreeMap<String, XProperty> persistentAttributeMap, TreeMap<String, XProperty> persistentAttributeMap,
Map<String,XProperty> persistentAttributesFromGetters, Map<String,XProperty> persistentAttributesFromGetters,
List<XProperty> fields, List<XProperty> fields,
@ -229,20 +238,30 @@ class PropertyContainer {
return classLevelAccessType; return classLevelAccessType;
} }
/**
* @deprecated Use the {@link #propertyIterator()} method instead.
*/
@Deprecated
public Collection<XProperty> getProperties() { public Collection<XProperty> getProperties() {
assertTypesAreResolvable(); return Collections.unmodifiableCollection( this.persistentAttributes );
return Collections.unmodifiableCollection( persistentAttributeMap.values() );
} }
private void assertTypesAreResolvable() { public Iterable<XProperty> propertyIterator() {
for ( XProperty xProperty : persistentAttributeMap.values() ) { return persistentAttributes;
}
private static List<XProperty> verifyAndInitializePersistentAttributes(XClass xClass, Map<String, XProperty> localAttributeMap) {
ArrayList<XProperty> output = new ArrayList( localAttributeMap.size() );
for ( XProperty xProperty : localAttributeMap.values() ) {
if ( !xProperty.isTypeResolved() && !discoverTypeWithoutReflection( xProperty ) ) { if ( !xProperty.isTypeResolved() && !discoverTypeWithoutReflection( xProperty ) ) {
String msg = "Property " + StringHelper.qualify( xClass.getName(), xProperty.getName() ) + String msg = "Property " + StringHelper.qualify( xClass.getName(), xProperty.getName() ) +
" has an unbound type and no explicit target entity. Resolve this Generic usage issue" + " 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"; " or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type";
throw new AnnotationException( msg ); throw new AnnotationException( msg );
} }
output.add( xProperty );
} }
return CollectionHelper.toSmallList( output );
} }
// //
// private void considerExplicitFieldAndPropertyAccess() { // private void considerExplicitFieldAndPropertyAccess() {