Skip to content

Commit 4c124cd

Browse files
committed
HHH-18506 Improve flush performance by reducing itable stubs
1 parent ec204e4 commit 4c124cd

37 files changed

+246
-173
lines changed

hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/HibernateTraversableResolver.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
import org.hibernate.Hibernate;
1616
import org.hibernate.engine.spi.SessionFactoryImplementor;
1717
import org.hibernate.persister.entity.EntityPersister;
18+
import org.hibernate.type.AnyType;
1819
import org.hibernate.type.CollectionType;
20+
import org.hibernate.type.ComponentType;
1921
import org.hibernate.type.CompositeType;
22+
import org.hibernate.type.EntityType;
2023
import org.hibernate.type.Type;
2124

2225
import jakarta.validation.Path;
@@ -54,17 +57,17 @@ private void addAssociationsToTheSetForAllProperties(String[] names, Type[] type
5457

5558
private void addAssociationsToTheSetForOneProperty(String name, Type type, String prefix, SessionFactoryImplementor factory) {
5659

57-
if ( type.isCollectionType() ) {
60+
if ( type instanceof CollectionType ) {
5861
CollectionType collType = (CollectionType) type;
5962
Type assocType = collType.getElementType( factory );
6063
addAssociationsToTheSetForOneProperty(name, assocType, prefix, factory);
6164
}
6265
//ToOne association
63-
else if ( type.isEntityType() || type.isAnyType() ) {
66+
else if ( type instanceof EntityType || type instanceof AnyType ) {
6467
associations.add( prefix + name );
6568
}
66-
else if ( type.isComponentType() ) {
67-
CompositeType componentType = (CompositeType) type;
69+
else if ( type instanceof ComponentType ) {
70+
ComponentType componentType = (ComponentType) type;
6871
addAssociationsToTheSetForAllProperties(
6972
componentType.getPropertyNames(),
7073
componentType.getSubtypes(),

hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/EnhancementAsProxyLazinessInterceptor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1717
import org.hibernate.metamodel.mapping.AttributeMapping;
1818
import org.hibernate.persister.entity.EntityPersister;
19+
import org.hibernate.type.CollectionType;
1920
import org.hibernate.type.CompositeType;
2021
import org.hibernate.type.Type;
2122

@@ -65,7 +66,7 @@ public EnhancementAsProxyLazinessInterceptor(
6566
collectionAttributeNames = new HashSet<>();
6667
for ( int i = 0; i < propertyTypes.length; i++ ) {
6768
Type propertyType = propertyTypes[i];
68-
if ( propertyType.isCollectionType() ) {
69+
if ( propertyType instanceof CollectionType ) {
6970
collectionAttributeNames.add( propertyNames[i] );
7071
}
7172
}

hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/interceptor/LazyAttributeDescriptor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package org.hibernate.bytecode.enhance.spi.interceptor;
88

99
import org.hibernate.mapping.Property;
10+
import org.hibernate.type.CollectionType;
1011
import org.hibernate.type.Type;
1112

1213
/**
@@ -21,7 +22,7 @@ public static LazyAttributeDescriptor from(
2122
int lazyIndex) {
2223
String fetchGroupName = property.getLazyGroup();
2324
if ( fetchGroupName == null ) {
24-
fetchGroupName = property.getType().isCollectionType()
25+
fetchGroupName = property.getType() instanceof CollectionType
2526
? property.getName()
2627
: "DEFAULT";
2728
}

hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,18 @@
2727
import org.hibernate.internal.CoreMessageLogger;
2828
import org.hibernate.persister.collection.CollectionPersister;
2929
import org.hibernate.persister.entity.EntityPersister;
30+
import org.hibernate.pretty.MessageHelper;
31+
import org.hibernate.proxy.HibernateProxy;
32+
import org.hibernate.type.AnyType;
3033
import org.hibernate.type.AssociationType;
3134
import org.hibernate.type.CollectionType;
3235
import org.hibernate.type.ComponentType;
3336
import org.hibernate.type.CompositeType;
3437
import org.hibernate.type.EntityType;
38+
import org.hibernate.type.ForeignKeyDirection;
3539
import org.hibernate.type.ManyToOneType;
3640
import org.hibernate.type.OneToOneType;
41+
import org.hibernate.type.OneToOneType;
3742
import org.hibernate.type.Type;
3843

3944
import static org.hibernate.engine.internal.ManagedTypeHelper.isHibernateProxy;
@@ -130,7 +135,7 @@ public static <T> void cascade(
130135
// parent was not in the PersistenceContext
131136
continue;
132137
}
133-
if ( type.isCollectionType() ) {
138+
if ( type instanceof CollectionType ) {
134139
// CollectionType#getCollection gets the PersistentCollection
135140
// that corresponds to the uninitialized collection from the
136141
// PersistenceContext. If not present, an uninitialized
@@ -145,13 +150,13 @@ public static <T> void cascade(
145150
null
146151
);
147152
}
148-
else if ( type.isComponentType() ) {
153+
else if ( type instanceof AnyType || type instanceof ComponentType ) {
149154
// Hibernate does not support lazy embeddables, so this shouldn't happen.
150155
throw new UnsupportedOperationException(
151156
"Lazy components are not supported."
152157
);
153158
}
154-
else if ( action.performOnLazyProperty() && type.isEntityType() ) {
159+
else if ( action.performOnLazyProperty() && type instanceof EntityType ) {
155160
// Only need to initialize a lazy entity attribute when action.performOnLazyProperty()
156161
// returns true.
157162
LazyAttributeLoadingInterceptor interceptor = persister.getBytecodeEnhancementMetadata()
@@ -222,7 +227,7 @@ private static <T> void cascadeProperty(
222227
final boolean isCascadeDeleteEnabled) throws HibernateException {
223228

224229
if ( child != null ) {
225-
if ( type.isAssociationType() ) {
230+
if ( type instanceof EntityType || type instanceof CollectionType || type instanceof AnyType ) {
226231
final AssociationType associationType = (AssociationType) type;
227232
final boolean unownedTransient = eventSource.getSessionFactory()
228233
.getSessionFactoryOptions()
@@ -242,7 +247,7 @@ private static <T> void cascadeProperty(
242247
);
243248
}
244249
}
245-
else if ( type.isComponentType() ) {
250+
else if ( type instanceof ComponentType ) {
246251
if ( componentPath == null && propertyName != null ) {
247252
componentPath = new ArrayList<>();
248253
}
@@ -359,8 +364,8 @@ private static <T> void cascadeLogicalOneToOneOrphanRemoval(
359364
);
360365
}
361366

362-
if ( type.isAssociationType()
363-
&& ( (AssociationType) type ).getForeignKeyDirection().equals(TO_PARENT) ) {
367+
if ( type instanceof CollectionType
368+
|| type instanceof OneToOneType && ( (OneToOneType) type ).getForeignKeyDirection() == ForeignKeyDirection.TO_PARENT ) {
364369
// If FK direction is to-parent, we must remove the orphan *before* the queued update(s)
365370
// occur. Otherwise, replacing the association on a managed entity, without manually
366371
// nulling and flushing, causes FK constraint violations.
@@ -400,19 +405,17 @@ private static boolean cascadeAssociationNow(
400405
}
401406

402407
private static boolean isUnownedAssociation(AssociationType associationType, SessionFactoryImplementor factory) {
403-
if ( associationType.isEntityType() ) {
404-
if ( associationType instanceof ManyToOneType ) {
405-
final ManyToOneType manyToOne = (ManyToOneType) associationType;
406-
// logical one-to-one + non-null unique key property name indicates unowned
407-
return manyToOne.isLogicalOneToOne() && manyToOne.getRHSUniqueKeyPropertyName() != null;
408-
}
409-
else if ( associationType instanceof OneToOneType ) {
410-
final OneToOneType oneToOne = (OneToOneType) associationType;
411-
// constrained false + non-null unique key property name indicates unowned
412-
return oneToOne.isNullable() && oneToOne.getRHSUniqueKeyPropertyName() != null;
413-
}
408+
if ( associationType instanceof ManyToOneType ) {
409+
final ManyToOneType manyToOne = (ManyToOneType) associationType;
410+
// logical one-to-one + non-null unique key property name indicates unowned
411+
return manyToOne.isLogicalOneToOne() && manyToOne.getRHSUniqueKeyPropertyName() != null;
412+
}
413+
else if ( associationType instanceof OneToOneType ) {
414+
final OneToOneType oneToOne = (OneToOneType) associationType;
415+
// constrained false + non-null unique key property name indicates unowned
416+
return oneToOne.isNullable() && oneToOne.getRHSUniqueKeyPropertyName() != null;
414417
}
415-
else if ( associationType.isCollectionType() ) {
418+
else if ( associationType instanceof CollectionType ) {
416419
// for collections, we can ask the persister if we're on the inverse side
417420
return ( (CollectionType) associationType ).isInverse( factory );
418421
}
@@ -468,10 +471,10 @@ private static <T> void cascadeAssociation(
468471
final CascadeStyle style,
469472
final T anything,
470473
final boolean isCascadeDeleteEnabled) {
471-
if ( type.isEntityType() || type.isAnyType() ) {
474+
if ( type instanceof EntityType || type instanceof AnyType ) {
472475
cascadeToOne( action, eventSource, parent, child, type, style, anything, isCascadeDeleteEnabled );
473476
}
474-
else if ( type.isCollectionType() ) {
477+
else if ( type instanceof CollectionType ) {
475478
cascadeCollection(
476479
action,
477480
cascadePoint,
@@ -510,7 +513,7 @@ private static <T> void cascadeCollection(
510513
}
511514

512515
//cascade to current collection elements
513-
if ( elemType.isEntityType() || elemType.isAnyType() || elemType.isComponentType() ) {
516+
if ( elemType instanceof EntityType || elemType instanceof AnyType || elemType instanceof ComponentType ) {
514517
cascadeCollectionElements(
515518
action,
516519
elementsCascadePoint,
@@ -539,7 +542,7 @@ private static <T> void cascadeToOne(
539542
final CascadeStyle style,
540543
final T anything,
541544
final boolean isCascadeDeleteEnabled) {
542-
final String entityName = type.isEntityType()
545+
final String entityName = type instanceof EntityType
543546
? ( (EntityType) type ).getAssociatedEntityName()
544547
: null;
545548
if ( style.reallyDoCascade( action ) ) {
@@ -603,7 +606,7 @@ private static <T> void cascadeCollectionElements(
603606

604607
final boolean deleteOrphans = style.hasOrphanDelete()
605608
&& action.deleteOrphans()
606-
&& elemType.isEntityType()
609+
&& elemType instanceof EntityType
607610
&& child instanceof PersistentCollection
608611
// a newly instantiated collection can't have orphans
609612
&& ! ( (PersistentCollection<?>) child ).isNewlyInstantiated();

hibernate-core/src/main/java/org/hibernate/engine/internal/ForeignKeys.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1717
import org.hibernate.persister.entity.EntityPersister;
1818
import org.hibernate.proxy.LazyInitializer;
19-
import org.hibernate.type.CompositeType;
19+
import org.hibernate.type.AnyType;
20+
import org.hibernate.type.ComponentType;
2021
import org.hibernate.type.EntityType;
2122
import org.hibernate.type.Type;
2223

@@ -106,21 +107,21 @@ private Object nullifyTransient(Object value, String propertyName, Type type) {
106107
if ( value == null ) {
107108
return null;
108109
}
109-
else if ( type.isEntityType() ) {
110+
else if ( type instanceof EntityType ) {
110111
return nullifyEntityType( value, propertyName, (EntityType) type );
111112
}
112-
else if ( type.isAnyType() ) {
113+
else if ( type instanceof AnyType ) {
113114
return isNullifiable( null, value) ? null : value;
114115
}
115-
else if ( type.isComponentType() ) {
116-
return nullifyCompositeType( value, propertyName, (CompositeType) type );
116+
else if ( type instanceof ComponentType ) {
117+
return nullifyCompositeType( value, propertyName, (ComponentType) type );
117118
}
118119
else {
119120
return value;
120121
}
121122
}
122123

123-
private Object nullifyCompositeType(Object value, String propertyName, CompositeType compositeType) {
124+
private Object nullifyCompositeType(Object value, String propertyName, ComponentType compositeType) {
124125
final Object[] subvalues = compositeType.getPropertyValues(value, session );
125126
final Type[] subtypes = compositeType.getSubtypes();
126127
final String[] subPropertyNames = compositeType.getPropertyNames();
@@ -194,7 +195,7 @@ private boolean initializationIsNecessary(Object value, Type type) {
194195
// more than just initializing the associated entity.
195196
return isDelete
196197
&& value == UNFETCHED_PROPERTY
197-
&& type.isEntityType()
198+
&& type instanceof EntityType
198199
&& !session.getPersistenceContextInternal().isNullifiableEntityKeysEmpty();
199200
}
200201

@@ -432,21 +433,21 @@ private static void collectNonNullableTransientEntities(
432433
if ( value == null ) {
433434
// do nothing
434435
}
435-
else if ( type.isEntityType() ) {
436+
else if ( type instanceof EntityType ) {
436437
final EntityType entityType = (EntityType) type;
437438
if ( !isNullable
438439
&& !entityType.isOneToOne()
439440
&& nullifier.isNullifiable( entityType.getAssociatedEntityName(), value ) ) {
440441
nonNullableTransientEntities.add( propertyName, value );
441442
}
442443
}
443-
else if ( type.isAnyType() ) {
444+
else if ( type instanceof AnyType ) {
444445
if ( !isNullable && nullifier.isNullifiable( null, value ) ) {
445446
nonNullableTransientEntities.add( propertyName, value );
446447
}
447448
}
448-
else if ( type.isComponentType() ) {
449-
final CompositeType compositeType = (CompositeType) type;
449+
else if ( type instanceof ComponentType ) {
450+
final ComponentType compositeType = (ComponentType) type;
450451
final boolean[] subValueNullability = compositeType.getPropertyNullability();
451452
if ( subValueNullability != null ) {
452453
final String[] subPropertyNames = compositeType.getPropertyNames();

hibernate-core/src/main/java/org/hibernate/engine/internal/Nullability.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1515
import org.hibernate.persister.entity.EntityPersister;
1616
import org.hibernate.generator.Generator;
17+
import org.hibernate.type.AnyType;
1718
import org.hibernate.type.CollectionType;
19+
import org.hibernate.type.ComponentType;
1820
import org.hibernate.type.CompositeType;
1921
import org.hibernate.type.Type;
2022

@@ -144,16 +146,19 @@ private static boolean generated(Generator generator) {
144146
* @throws HibernateException error while getting subcomponent values
145147
*/
146148
private String checkSubElementsNullability(Type propertyType, Object value) throws HibernateException {
147-
if ( propertyType.isComponentType() ) {
148-
return checkComponentNullability( value, (CompositeType) propertyType );
149+
if ( propertyType instanceof AnyType ) {
150+
return checkComponentNullability( value, (AnyType) propertyType );
151+
}
152+
if ( propertyType instanceof ComponentType ) {
153+
return checkComponentNullability( value, (ComponentType) propertyType );
149154
}
150155

151-
if ( propertyType.isCollectionType() ) {
156+
if ( propertyType instanceof CollectionType ) {
152157
// persistent collections may have components
153158
final CollectionType collectionType = (CollectionType) propertyType;
154159
final Type collectionElementType = collectionType.getElementType( session.getFactory() );
155160

156-
if ( collectionElementType.isComponentType() ) {
161+
if ( collectionElementType instanceof ComponentType || collectionElementType instanceof AnyType ) {
157162
// check for all components values in the collection
158163
final CompositeType componentType = (CompositeType) collectionElementType;
159164
final Iterator<?> itr = getLoadedElementsIterator( session, collectionType, value );
@@ -189,7 +194,7 @@ private String checkComponentNullability(Object value, CompositeType compositeTy
189194
//
190195
// The more correct fix would be to cascade saves of the many-to-any elements before the Nullability checking
191196

192-
if ( compositeType.isAnyType() ) {
197+
if ( compositeType instanceof AnyType ) {
193198
return null;
194199
}
195200

hibernate-core/src/main/java/org/hibernate/engine/profile/FetchProfile.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.hibernate.internal.CoreMessageLogger;
1515
import org.hibernate.persister.entity.EntityPersister;
1616
import org.hibernate.type.BagType;
17+
import org.hibernate.type.CollectionType;
1718
import org.hibernate.type.Type;
1819

1920
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -98,7 +99,7 @@ public void addFetch(final Fetch fetch) {
9899
final String role = association.getRole();
99100
final Type associationType =
100101
association.getOwner().getPropertyType( association.getAssociationPath() );
101-
if ( associationType.isCollectionType() ) {
102+
if ( associationType instanceof CollectionType ) {
102103
LOG.tracev( "Handling request to add collection fetch [{0}]", role );
103104

104105
// couple of things for which to account in the case of collection

hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
import org.hibernate.persister.entity.EntityPersister;
5353
import org.hibernate.proxy.LazyInitializer;
5454
import org.hibernate.type.CollectionType;
55-
import org.hibernate.type.CompositeType;
55+
import org.hibernate.type.ComponentType;
5656
import org.hibernate.type.EntityType;
5757
import org.hibernate.type.ForeignKeyDirection;
5858
import org.hibernate.type.Type;
@@ -1167,7 +1167,10 @@ public void addTransitiveDependencies(InsertInfo origin, Set<InsertInfo> visited
11671167
}
11681168

11691169
private void addDirectDependency(Type type, @Nullable Object value, IdentityHashMap<Object, InsertInfo> insertInfosByEntity) {
1170-
if ( type.isEntityType() && value != null ) {
1170+
if ( value == null ) {
1171+
return;
1172+
}
1173+
if ( type instanceof EntityType ) {
11711174
final EntityType entityType = (EntityType) type;
11721175
final InsertInfo insertInfo = insertInfosByEntity.get( value );
11731176
if ( insertInfo != null ) {
@@ -1188,7 +1191,7 @@ private void addDirectDependency(Type type, @Nullable Object value, IdentityHash
11881191
}
11891192
}
11901193
}
1191-
else if ( type.isCollectionType() && value != null ) {
1194+
else if ( type instanceof CollectionType ) {
11921195
CollectionType collectionType = (CollectionType) type;
11931196
final PluralAttributeMapping pluralAttributeMapping = insertAction.getSession()
11941197
.getFactory()
@@ -1212,9 +1215,9 @@ else if ( type.isCollectionType() && value != null ) {
12121215
}
12131216
}
12141217
}
1215-
else if ( type.isComponentType() && value != null ) {
1218+
else if ( type instanceof ComponentType ) {
12161219
// Support recursive checks of composite type properties for associations and collections.
1217-
final CompositeType compositeType = (CompositeType) type;
1220+
ComponentType compositeType = (ComponentType) type;
12181221
final SharedSessionContractImplementor session = insertAction.getSession();
12191222
final Object[] componentValues = compositeType.getPropertyValues( value, session );
12201223
for ( int j = 0; j < componentValues.length; ++j ) {

0 commit comments

Comments
 (0)