Skip to content

Commit 73af6a0

Browse files
committed
HHH-18410 Make use of getter/setter cache as much as possible
1 parent 7ef2691 commit 73af6a0

26 files changed

+174
-113
lines changed

hibernate-core/src/main/java/org/hibernate/action/internal/AbstractEntityInsertAction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,14 @@ private void visitEmbeddedAttributeMapping(
180180
if ( attribute.isPluralAttributeMapping() ) {
181181
addCollectionKey(
182182
attribute.asPluralAttributeMapping(),
183-
attribute.getPropertyAccess().getGetter().get( object ),
183+
attribute.getValue( object ),
184184
persistenceContext
185185
);
186186
}
187187
else if ( attribute.isEmbeddedAttributeMapping() ) {
188188
visitEmbeddedAttributeMapping(
189189
attribute.asEmbeddedAttributeMapping(),
190-
attribute.getPropertyAccess().getGetter().get( object ),
190+
attribute.getValue( object ),
191191
persistenceContext
192192
);
193193
}

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,16 @@ public static <T> void cascade(
8686
LOG.tracev( "Processing cascade {0} for: {1}", action, persister.getEntityName() );
8787
}
8888
final PersistenceContext persistenceContext = eventSource.getPersistenceContextInternal();
89-
final EntityEntry entry = persistenceContext.getEntry( parent );
90-
if ( entry != null && entry.getLoadedState() == null && entry.getStatus() == Status.MANAGED && persister.getBytecodeEnhancementMetadata()
91-
.isEnhancedForLazyLoading() ) {
92-
return;
89+
final boolean enhancedForLazyLoading = persister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
90+
final EntityEntry entry;
91+
if ( enhancedForLazyLoading ) {
92+
entry = persistenceContext.getEntry( parent );
93+
if ( entry != null && entry.getLoadedState() == null && entry.getStatus() == Status.MANAGED ) {
94+
return;
95+
}
96+
}
97+
else {
98+
entry = null;
9399
}
94100
final Type[] types = persister.getPropertyTypes();
95101
final String[] propertyNames = persister.getPropertyNames();
@@ -107,6 +113,7 @@ public static <T> void cascade(
107113
if ( style.doCascade( action ) ) {
108114
final Object child;
109115
if ( isUninitializedProperty ) {
116+
assert enhancedForLazyLoading;
110117
// parent is a bytecode enhanced entity.
111118
// Cascade to an uninitialized, lazy value only if
112119
// parent is managed in the PersistenceContext.
@@ -216,7 +223,7 @@ private static <T> void cascadeProperty(
216223
final String propertyName,
217224
final T anything,
218225
final boolean isCascadeDeleteEnabled) throws HibernateException {
219-
226+
220227
if ( child != null ) {
221228
if ( type.isAssociationType() ) {
222229
final AssociationType associationType = (AssociationType) type;
@@ -378,7 +385,7 @@ private static <T> void cascadeLogicalOneToOneOrphanRemoval(
378385
* @return True if the attribute represents a logical one to one association
379386
*/
380387
private static boolean isLogicalOneToOne(Type type) {
381-
return type.isEntityType() && ( (EntityType) type ).isLogicalOneToOne();
388+
return type instanceof EntityType && ( (EntityType) type ).isLogicalOneToOne();
382389
}
383390

384391
private static boolean cascadeAssociationNow(final CascadePoint cascadePoint, AssociationType associationType) {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,7 @@ public static void processReachableCollection(
145145
Object entity,
146146
SessionImplementor session) {
147147
collection.setOwner( entity );
148-
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
149-
final CollectionEntry ce = persistenceContext.getCollectionEntry( collection );
148+
final CollectionEntry ce = session.getPersistenceContextInternal().getCollectionEntry( collection );
150149

151150
if ( ce == null ) {
152151
// refer to comment in StatefulPersistenceContext.addCollection()

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ public int getNumberOfManagedEntities() {
13161316
@Override
13171317
@Deprecated
13181318
public Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries() {
1319-
return getOrInitializeCollectionEntries();
1319+
return collectionEntries;
13201320
}
13211321

13221322
@Override

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -521,11 +521,11 @@ EntityHolder claimEntityHolderIfPossible(
521521
JdbcValuesSourceProcessingState processingState,
522522
EntityInitializer initializer);
523523

524-
EntityHolder getEntityHolder(EntityKey key);
524+
@Nullable EntityHolder getEntityHolder(EntityKey key);
525525

526526
boolean containsEntityHolder(EntityKey key);
527527

528-
EntityHolder removeEntityHolder(EntityKey key);
528+
@Nullable EntityHolder removeEntityHolder(EntityKey key);
529529

530530
@Incubating
531531
void postLoad(JdbcValuesSourceProcessingState processingState, Consumer<EntityHolder> loadedConsumer);
@@ -564,7 +564,7 @@ EntityHolder claimEntityHolderIfPossible(
564564
* Doubly internal
565565
*/
566566
@Internal
567-
Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries();
567+
@Nullable Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries();
568568

569569
/**
570570
* Execute some action on each entry of the collectionEntries map, optionally iterating on a defensive copy.

hibernate-core/src/main/java/org/hibernate/event/internal/AbstractFlushingEventListener.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
import org.hibernate.action.internal.CollectionRemoveAction;
1515
import org.hibernate.action.internal.CollectionUpdateAction;
1616
import org.hibernate.action.internal.QueuedOperationCollectionAction;
17+
import org.hibernate.collection.spi.PersistentCollection;
1718
import org.hibernate.engine.internal.Cascade;
1819
import org.hibernate.engine.internal.CascadePoint;
1920
import org.hibernate.engine.internal.Collections;
2021
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
2122
import org.hibernate.engine.spi.ActionQueue;
2223
import org.hibernate.engine.spi.CascadingAction;
2324
import org.hibernate.engine.spi.CascadingActions;
25+
import org.hibernate.engine.spi.CollectionEntry;
2426
import org.hibernate.engine.spi.CollectionKey;
2527
import org.hibernate.engine.spi.EntityEntry;
2628
import org.hibernate.engine.spi.PersistenceContext;
@@ -35,6 +37,7 @@
3537
import org.hibernate.event.spi.PersistContext;
3638
import org.hibernate.internal.CoreMessageLogger;
3739
import org.hibernate.internal.util.EntityPrinter;
40+
import org.hibernate.internal.util.collections.IdentityMap;
3841
import org.hibernate.persister.entity.EntityPersister;
3942

4043
import org.jboss.logging.Logger;
@@ -183,7 +186,12 @@ private void prepareCollectionFlushes(PersistenceContext persistenceContext) thr
183186
// and reset reached, doupdate, etc.
184187

185188
LOG.debug( "Dirty checking collections" );
186-
persistenceContext.forEachCollectionEntry( (pc,ce) -> ce.preFlush( pc ), true );
189+
final Map<PersistentCollection<?>, CollectionEntry> collectionEntries = persistenceContext.getCollectionEntries();
190+
if ( collectionEntries != null ) {
191+
for ( Map.Entry<PersistentCollection<?>, CollectionEntry> entry : ( (IdentityMap<PersistentCollection<?>, CollectionEntry>) collectionEntries ).entryArray() ) {
192+
entry.getValue().preFlush( entry.getKey() );
193+
}
194+
}
187195
}
188196

189197
/**
@@ -262,14 +270,20 @@ private int flushCollections(final EventSource session, final PersistenceContext
262270
throws HibernateException {
263271
LOG.trace( "Processing unreferenced collections" );
264272

265-
final int count = persistenceContext.getCollectionEntriesSize();
266-
267-
persistenceContext.forEachCollectionEntry(
268-
(persistentCollection, collectionEntry) -> {
269-
if ( !collectionEntry.isReached() && !collectionEntry.isIgnore() ) {
270-
Collections.processUnreachableCollection( persistentCollection, session );
271-
}
272-
}, true );
273+
final Map<PersistentCollection<?>, CollectionEntry> collectionEntries = persistenceContext.getCollectionEntries();
274+
final int count;
275+
if ( collectionEntries == null ) {
276+
count = 0;
277+
}
278+
else {
279+
count = collectionEntries.size();
280+
for ( Map.Entry<PersistentCollection<?>, CollectionEntry> me : ( (IdentityMap<PersistentCollection<?>, CollectionEntry>) collectionEntries ).entryArray() ) {
281+
final CollectionEntry ce = me.getValue();
282+
if ( !ce.isReached() && !ce.isIgnore() ) {
283+
Collections.processUnreachableCollection( me.getKey(), session );
284+
}
285+
}
286+
}
273287

274288
// Schedule updates to collections:
275289

hibernate-core/src/main/java/org/hibernate/event/internal/DefaultMergeEventListener.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,7 @@ protected Object processCollection(Object collection, CollectionType collectionT
350350
.getMappingMetamodel()
351351
.getCollectionDescriptor( collectionType.getRole() );
352352
final CollectionEntry collectionEntry = getSession().getPersistenceContextInternal()
353-
.getCollectionEntries()
354-
.get( coll );
353+
.getCollectionEntry( coll );
355354
if ( !coll.equalsSnapshot( persister ) ) {
356355
collectionEntry.resetStoredSnapshot( coll, coll.getSnapshot( persister ) );
357356
}

hibernate-core/src/main/java/org/hibernate/internal/util/collections/IdentityMap.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public final class IdentityMap<K,V> implements Map<K,V> {
2424

2525
private final LinkedHashMap<IdentityKey<K>,V> map;
2626

27-
private transient Entry<IdentityKey<K>,V>[] entryArray = null;
27+
private transient Entry<K,V>[] entryArray = null;
2828

2929
/**
3030
* Return a new instance of this class, with iteration
@@ -151,15 +151,14 @@ public Set<Entry<K,V>> entrySet() {
151151
return set;
152152
}
153153

154-
@SuppressWarnings( {"unchecked"})
155-
public Entry[] entryArray() {
154+
public Entry<K,V>[] entryArray() {
156155
if ( entryArray == null ) {
157156
entryArray = new Entry[ map.size() ];
158157
final Iterator<Entry<IdentityKey<K>, V>> itr = map.entrySet().iterator();
159158
int i = 0;
160159
while ( itr.hasNext() ) {
161160
final Entry<IdentityKey<K>, V> me = itr.next();
162-
entryArray[i++] = new IdentityMapEntry( me.getKey().key, me.getValue() );
161+
entryArray[i++] = new IdentityMapEntry<>( me.getKey().key, me.getValue() );
163162
}
164163
}
165164
return entryArray;

hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ public <X, Y> int forEachJdbcValue(
185185
else {
186186
for ( int i = 0; i < size; i++ ) {
187187
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
188-
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
188+
final Object o = embeddableTypeDescriptor.getValue( value, i );
189189
if ( attributeMapping instanceof ToOneAttributeMapping ) {
190190
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
191191
final ForeignKeyDescriptor fkDescriptor = toOneAttributeMapping.getForeignKeyDescriptor();

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/AttributeMapping.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ default String getPartName() {
5656
* Convenient access to getting the value for this attribute from the declarer
5757
*/
5858
default Object getValue(Object container) {
59-
return getPropertyAccess().getGetter().get( container );
59+
return getDeclaringType().getValue( container, getStateArrayPosition() );
6060
}
6161

6262
/**
6363
* Convenient access to setting the value for this attribute on the declarer
6464
*/
6565
default void setValue(Object container, Object value) {
66-
getPropertyAccess().getSetter().set( container, value );
66+
getDeclaringType().setValue( container, getStateArrayPosition(), value );
6767
}
6868

6969
/**

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EmbeddableMappingType.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,8 @@ default void applySqlSelections(
262262
default int compare(Object value1, Object value2) {
263263
final AttributeMappingsList attributeMappings = getAttributeMappings();
264264
for ( int i = 0; i < attributeMappings.size(); i++ ) {
265-
AttributeMapping attributeMapping = attributeMappings.get( i );
266-
final Getter getter = attributeMapping.getPropertyAccess().getGetter();
267-
final int comparison = attributeMapping.compare( getter.get( value1 ), getter.get( value2 ) );
265+
final AttributeMapping attribute = attributeMappings.get( i );
266+
final int comparison = attribute.compare( attribute.getValue( value1 ), attribute.getValue( value2 ) );
268267
if ( comparison != 0 ) {
269268
return comparison;
270269
}

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/ManagedMappingType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ default void forEachAttributeMapping(IndexedConsumer<? super AttributeMapping> c
7373
* Extract a specific attribute value from the entity instance, by position
7474
*/
7575
default Object getValue(Object instance, int position) {
76-
return getAttributeMapping( position ).getValue( instance );
76+
return getAttributeMapping( position ).getPropertyAccess().getGetter().get( instance );
7777
}
7878

7979
/**
@@ -85,7 +85,7 @@ default Object getValue(Object instance, int position) {
8585
* Inject a specific attribute value into the entity instance, by position
8686
*/
8787
default void setValue(Object instance, int position, Object value) {
88-
getAttributeMapping( position ).setValue( instance, value );
88+
getAttributeMapping( position ).getPropertyAccess().getSetter().set( instance, value );
8989
}
9090

9191
default boolean anyRequiresAggregateColumnWriter() {

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/AbstractEmbeddableMapping.java

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
5252
import org.hibernate.property.access.spi.Getter;
5353
import org.hibernate.property.access.spi.PropertyAccess;
54+
import org.hibernate.property.access.spi.Setter;
5455
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
5556
import org.hibernate.sql.results.graph.Fetchable;
5657
import org.hibernate.type.AnyType;
@@ -70,6 +71,8 @@
7071
public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType {
7172
final protected MutableAttributeMappingList attributeMappings;
7273
protected SelectableMappings selectableMappings;
74+
protected Getter[] getterCache;
75+
protected Setter[] setterCache;
7376

7477
public AbstractEmbeddableMapping(MutableAttributeMappingList attributeMappings) {
7578
this.attributeMappings = attributeMappings;
@@ -80,6 +83,16 @@ public JavaType<?> getMappedJavaType() {
8083
return getRepresentationStrategy().getMappedJavaType();
8184
}
8285

86+
@Override
87+
public Object getValue(Object instance, int position) {
88+
return getterCache[position].get( instance );
89+
}
90+
91+
@Override
92+
public void setValue(Object instance, int position, Object value) {
93+
setterCache[position].set( instance, value );
94+
}
95+
8396
@Override
8497
public Object[] getValues(Object compositeInstance) {
8598
if ( compositeInstance == PropertyAccessStrategyBackRefImpl.UNKNOWN ) {
@@ -93,10 +106,7 @@ public Object[] getValues(Object compositeInstance) {
93106

94107
final Object[] results = new Object[getNumberOfAttributeMappings()];
95108
for ( int i = 0; i < results.length; i++ ) {
96-
final Getter getter = getAttributeMapping( i ).getAttributeMetadata()
97-
.getPropertyAccess()
98-
.getGetter();
99-
results[i] = getter.get( compositeInstance );
109+
results[i] = getValue( compositeInstance, i );
100110
}
101111
return results;
102112
}
@@ -109,7 +119,7 @@ public void setValues(Object component, Object[] values) {
109119
}
110120
else {
111121
for ( int i = 0; i < values.length; i++ ) {
112-
getAttributeMapping( i ).getPropertyAccess().getSetter().set( component, values[i] );
122+
setValue( component, i,values[i] );
113123
}
114124
}
115125
}
@@ -215,6 +225,7 @@ else if ( attributeMapping instanceof EmbeddableValuedModelPart ) {
215225
}
216226
mappings.add( attributeMapping );
217227
}
228+
buildGetterSetterCache();
218229
return true;
219230
}
220231

@@ -686,7 +697,7 @@ public <X, Y> int forEachJdbcValue(
686697
if ( attributeMapping instanceof PluralAttributeMapping ) {
687698
continue;
688699
}
689-
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
700+
final Object o = getValue( value, i );
690701
span += attributeMapping.forEachJdbcValue( o, span + offset, x, y, valuesConsumer, session );
691702
}
692703
}
@@ -722,10 +733,24 @@ protected boolean initColumnMappings() {
722733
);
723734

724735
this.selectableMappings = new SelectableMappingsImpl( selectableMappings.toArray( new SelectableMapping[0] ) );
736+
buildGetterSetterCache();
725737

726738
return true;
727739
}
728740

741+
protected void buildGetterSetterCache() {
742+
final int propertySpan = attributeMappings.size();
743+
final Getter[] getterCache = new Getter[propertySpan];
744+
final Setter[] setterCache = new Setter[propertySpan];
745+
for ( int i = 0; i < propertySpan; i++ ) {
746+
final PropertyAccess propertyAccess = attributeMappings.get( i ).getPropertyAccess();
747+
getterCache[i] = propertyAccess.getGetter();
748+
setterCache[i] = propertyAccess.getSetter();
749+
}
750+
this.getterCache = getterCache;
751+
this.setterCache = setterCache;
752+
}
753+
729754
private static MutabilityPlan<?> getMutabilityPlan(boolean updateable) {
730755
if ( updateable ) {
731756
return new MutabilityPlan<>() {

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.hibernate.metamodel.mapping.EntityMappingType;
3838
import org.hibernate.metamodel.mapping.JdbcMapping;
3939
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
40+
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
4041
import org.hibernate.metamodel.mapping.SelectableConsumer;
4142
import org.hibernate.metamodel.mapping.SelectableMapping;
4243
import org.hibernate.metamodel.mapping.SelectableMappings;
@@ -658,7 +659,7 @@ public <X, Y> int breakDownJdbcValues(
658659
if ( !attributeMapping.isPluralAttributeMapping() ) {
659660
final Object attributeValue = domainValue == null
660661
? null
661-
: attributeMapping.getPropertyAccess().getGetter().get( domainValue );
662+
: getValue( domainValue, i );
662663
span += attributeMapping.breakDownJdbcValues(
663664
attributeValue,
664665
offset + span,

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ public EmbeddedAttributeMapping(
143143
MappingModelCreationProcess creationProcess) {
144144
super(
145145
inverseModelPart.getFetchableName(),
146-
-1,
146+
inverseModelPart.asAttributeMapping() != null
147+
? inverseModelPart.asAttributeMapping().getStateArrayPosition()
148+
: -1,
147149
inverseModelPart.getFetchableKey(),
148150
inverseModelPart.asAttributeMapping() != null
149151
? inverseModelPart.asAttributeMapping().getAttributeMetadata()

0 commit comments

Comments
 (0)