HHH-14305 Reduce retained memory consumption of SingleTableEntityPersister

This commit is contained in:
Sanne Grinovero 2020-10-29 10:09:17 +00:00
parent 820fe56aa4
commit e9278288a7
1 changed files with 20 additions and 8 deletions

View File

@ -28,6 +28,7 @@ import org.hibernate.internal.DynamicFilterAliasGenerator;
import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.util.MarkerObject; import org.hibernate.internal.util.MarkerObject;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Column; import org.hibernate.mapping.Column;
import org.hibernate.mapping.Formula; import org.hibernate.mapping.Formula;
import org.hibernate.mapping.Join; import org.hibernate.mapping.Join;
@ -89,7 +90,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
private final int[] subclassFormulaTableNumberClosure; private final int[] subclassFormulaTableNumberClosure;
// discriminator column // discriminator column
private final Map<Object, String> subclassesByDiscriminatorValue = new HashMap<Object, String>(); private final Map<Object, String> subclassesByDiscriminatorValue;
private final boolean forceDiscriminator; private final boolean forceDiscriminator;
private final String discriminatorColumnName; private final String discriminatorColumnName;
private final String discriminatorColumnReaders; private final String discriminatorColumnReaders;
@ -106,9 +107,10 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
private final String[][] constraintOrderedKeyColumnNames; private final String[][] constraintOrderedKeyColumnNames;
//private final Map propertyTableNumbersByName = new HashMap(); //private final Map propertyTableNumbersByName = new HashMap();
private final Map<String, Integer> propertyTableNumbersByNameAndSubclass = new HashMap<String, Integer>(); private final Map<String, Integer> propertyTableNumbersByNameAndSubclass;
private final Map<String, String> sequentialSelectStringsByEntityName = new HashMap<String, String>(); //Efficiency note: try to not allocate an HashMap if we're not going to need it.
private final Map<String, String> sequentialSelectStringsByEntityName;
private static final Object NULL_DISCRIMINATOR = new MarkerObject( "<null discriminator>" ); private static final Object NULL_DISCRIMINATOR = new MarkerObject( "<null discriminator>" );
private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject( "<not null discriminator>" ); private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject( "<not null discriminator>" );
@ -370,6 +372,9 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
ArrayList<Integer> formulaJoinedNumbers = new ArrayList<Integer>(); ArrayList<Integer> formulaJoinedNumbers = new ArrayList<Integer>();
ArrayList<Integer> propertyJoinNumbers = new ArrayList<Integer>(); ArrayList<Integer> propertyJoinNumbers = new ArrayList<Integer>();
final HashMap<String, Integer> propertyTableNumbersByNameAndSubclassLocal = new HashMap<>();
final Map<Object, String> subclassesByDiscriminatorValueLocal = new HashMap<>();
iter = persistentClass.getSubclassPropertyClosureIterator(); iter = persistentClass.getSubclassPropertyClosureIterator();
while ( iter.hasNext() ) { while ( iter.hasNext() ) {
Property prop = (Property) iter.next(); Property prop = (Property) iter.next();
@ -377,7 +382,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
propertyJoinNumbers.add( join ); propertyJoinNumbers.add( join );
//propertyTableNumbersByName.put( prop.getName(), join ); //propertyTableNumbersByName.put( prop.getName(), join );
propertyTableNumbersByNameAndSubclass.put( propertyTableNumbersByNameAndSubclassLocal.put(
prop.getPersistentClass().getEntityName() + '.' + prop.getName(), prop.getPersistentClass().getEntityName() + '.' + prop.getName(),
join join
); );
@ -393,6 +398,9 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
} }
} }
} }
propertyTableNumbersByNameAndSubclass = CollectionHelper.toSmallMap( propertyTableNumbersByNameAndSubclassLocal );
subclassColumnTableNumberClosure = ArrayHelper.toIntArray( columnJoinNumbers ); subclassColumnTableNumberClosure = ArrayHelper.toIntArray( columnJoinNumbers );
subclassFormulaTableNumberClosure = ArrayHelper.toIntArray( formulaJoinedNumbers ); subclassFormulaTableNumberClosure = ArrayHelper.toIntArray( formulaJoinedNumbers );
subclassPropertyTableNumberClosure = ArrayHelper.toIntArray( propertyJoinNumbers ); subclassPropertyTableNumberClosure = ArrayHelper.toIntArray( propertyJoinNumbers );
@ -401,7 +409,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
subclassClosure = new String[subclassSpan]; subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName(); subclassClosure[0] = getEntityName();
if ( persistentClass.isPolymorphic() ) { if ( persistentClass.isPolymorphic() ) {
addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() ); addSubclassByDiscriminatorValue( subclassesByDiscriminatorValueLocal, discriminatorValue, getEntityName() );
} }
// SUBCLASSES // SUBCLASSES
@ -412,15 +420,16 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
Subclass sc = (Subclass) iter.next(); Subclass sc = (Subclass) iter.next();
subclassClosure[k++] = sc.getEntityName(); subclassClosure[k++] = sc.getEntityName();
if ( sc.isDiscriminatorValueNull() ) { if ( sc.isDiscriminatorValueNull() ) {
addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, sc.getEntityName() ); addSubclassByDiscriminatorValue( subclassesByDiscriminatorValueLocal, NULL_DISCRIMINATOR, sc.getEntityName() );
} }
else if ( sc.isDiscriminatorValueNotNull() ) { else if ( sc.isDiscriminatorValueNotNull() ) {
addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, sc.getEntityName() ); addSubclassByDiscriminatorValue( subclassesByDiscriminatorValueLocal, NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
} }
else { else {
try { try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType; DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
addSubclassByDiscriminatorValue( addSubclassByDiscriminatorValue(
subclassesByDiscriminatorValueLocal,
dtype.stringToObject( sc.getDiscriminatorValue() ), dtype.stringToObject( sc.getDiscriminatorValue() ),
sc.getEntityName() sc.getEntityName()
); );
@ -435,13 +444,16 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
} }
} }
// Don't hold a reference to an empty HashMap:
this.subclassesByDiscriminatorValue = CollectionHelper.toSmallMap( subclassesByDiscriminatorValueLocal );
initSubclassPropertyAliasesMap( persistentClass ); initSubclassPropertyAliasesMap( persistentClass );
postConstruct( creationContext.getMetadata() ); postConstruct( creationContext.getMetadata() );
} }
private void addSubclassByDiscriminatorValue(Object discriminatorValue, String entityName) { private static void addSubclassByDiscriminatorValue(Map<Object, String> subclassesByDiscriminatorValue, Object discriminatorValue, String entityName) {
String mappedEntityName = subclassesByDiscriminatorValue.put( discriminatorValue, entityName ); String mappedEntityName = subclassesByDiscriminatorValue.put( discriminatorValue, entityName );
if ( mappedEntityName != null ) { if ( mappedEntityName != null ) {
throw new MappingException( throw new MappingException(