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.util.MarkerObject;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Formula;
import org.hibernate.mapping.Join;
@ -89,7 +90,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
private final int[] subclassFormulaTableNumberClosure;
// discriminator column
private final Map<Object, String> subclassesByDiscriminatorValue = new HashMap<Object, String>();
private final Map<Object, String> subclassesByDiscriminatorValue;
private final boolean forceDiscriminator;
private final String discriminatorColumnName;
private final String discriminatorColumnReaders;
@ -106,9 +107,10 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
private final String[][] constraintOrderedKeyColumnNames;
//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 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> propertyJoinNumbers = new ArrayList<Integer>();
final HashMap<String, Integer> propertyTableNumbersByNameAndSubclassLocal = new HashMap<>();
final Map<Object, String> subclassesByDiscriminatorValueLocal = new HashMap<>();
iter = persistentClass.getSubclassPropertyClosureIterator();
while ( iter.hasNext() ) {
Property prop = (Property) iter.next();
@ -377,7 +382,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
propertyJoinNumbers.add( join );
//propertyTableNumbersByName.put( prop.getName(), join );
propertyTableNumbersByNameAndSubclass.put(
propertyTableNumbersByNameAndSubclassLocal.put(
prop.getPersistentClass().getEntityName() + '.' + prop.getName(),
join
);
@ -393,6 +398,9 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
}
}
}
propertyTableNumbersByNameAndSubclass = CollectionHelper.toSmallMap( propertyTableNumbersByNameAndSubclassLocal );
subclassColumnTableNumberClosure = ArrayHelper.toIntArray( columnJoinNumbers );
subclassFormulaTableNumberClosure = ArrayHelper.toIntArray( formulaJoinedNumbers );
subclassPropertyTableNumberClosure = ArrayHelper.toIntArray( propertyJoinNumbers );
@ -401,7 +409,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
subclassClosure = new String[subclassSpan];
subclassClosure[0] = getEntityName();
if ( persistentClass.isPolymorphic() ) {
addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() );
addSubclassByDiscriminatorValue( subclassesByDiscriminatorValueLocal, discriminatorValue, getEntityName() );
}
// SUBCLASSES
@ -412,15 +420,16 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
Subclass sc = (Subclass) iter.next();
subclassClosure[k++] = sc.getEntityName();
if ( sc.isDiscriminatorValueNull() ) {
addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, sc.getEntityName() );
addSubclassByDiscriminatorValue( subclassesByDiscriminatorValueLocal, NULL_DISCRIMINATOR, sc.getEntityName() );
}
else if ( sc.isDiscriminatorValueNotNull() ) {
addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
addSubclassByDiscriminatorValue( subclassesByDiscriminatorValueLocal, NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
}
else {
try {
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
addSubclassByDiscriminatorValue(
subclassesByDiscriminatorValueLocal,
dtype.stringToObject( sc.getDiscriminatorValue() ),
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 );
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 );
if ( mappedEntityName != null ) {
throw new MappingException(