Skip to content

Commit ba05533

Browse files
committed
HHH-18379 Allow passing row count estimate to pre-size collections
1 parent 33b2e36 commit ba05533

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+509
-99
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@
197197
import org.jboss.logging.Logger;
198198

199199
import jakarta.persistence.TemporalType;
200+
import org.checkerframework.checker.nullness.qual.Nullable;
200201

201202
import static java.lang.Math.ceil;
202203
import static java.lang.Math.log;
@@ -3189,7 +3190,7 @@ public Set<String> getKeywords() {
31893190
*/
31903191
public IdentifierHelper buildIdentifierHelper(
31913192
IdentifierHelperBuilder builder,
3192-
DatabaseMetaData dbMetaData) throws SQLException {
3193+
@Nullable DatabaseMetaData dbMetaData) throws SQLException {
31933194
builder.applyIdentifierCasing( dbMetaData );
31943195
builder.applyReservedWords( sqlKeywords );
31953196
builder.setNameQualifierSupport( getNameQualifierSupport() );
@@ -4356,7 +4357,7 @@ public boolean supportsPartitionBy() {
43564357
* an exception. Just rethrow and Hibernate will
43574358
* handle it.
43584359
*/
4359-
public boolean supportsNamedParameters(DatabaseMetaData databaseMetaData) throws SQLException {
4360+
public boolean supportsNamedParameters(@Nullable DatabaseMetaData databaseMetaData) throws SQLException {
43604361
return databaseMetaData != null && databaseMetaData.supportsNamedParameters();
43614362
}
43624363

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractNaturalIdLoader.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.hibernate.sql.exec.spi.JdbcParametersList;
5151
import org.hibernate.sql.results.graph.*;
5252
import org.hibernate.sql.results.graph.internal.ImmutableFetchList;
53+
import org.hibernate.sql.results.internal.RowTransformerSingularReturnImpl;
5354
import org.hibernate.sql.results.spi.ListResultsConsumer;
5455

5556
import static java.util.Collections.emptyList;
@@ -134,13 +135,14 @@ public T load(Object naturalIdValue, NaturalIdLoadOptions options, SharedSession
134135

135136
final long startToken = sessionFactory.getStatistics().isStatisticsEnabled() ? System.nanoTime() : -1;
136137

137-
//noinspection unchecked
138138
final List<T> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
139139
jdbcSelect,
140140
jdbcParamBindings,
141141
new NaturalIdLoaderWithOptionsExecutionContext( session, queryOptions ),
142-
row -> (T) row[0],
143-
ListResultsConsumer.UniqueSemantic.FILTER
142+
RowTransformerSingularReturnImpl.instance(),
143+
null,
144+
ListResultsConsumer.UniqueSemantic.FILTER,
145+
1
144146
);
145147

146148
if ( results.size() > 1 ) {
@@ -230,13 +232,14 @@ protected <L> L selectByNaturalId(
230232

231233
final Long startToken = statementStartHandler.apply( sessionFactory.getStatistics().isStatisticsEnabled() );
232234

233-
//noinspection unchecked
234235
final List<L> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
235236
jdbcSelect,
236237
jdbcParamBindings,
237238
new NaturalIdLoaderWithOptionsExecutionContext( session, queryOptions ),
238-
row -> (L) row[0],
239-
ListResultsConsumer.UniqueSemantic.FILTER
239+
RowTransformerSingularReturnImpl.instance(),
240+
null,
241+
ListResultsConsumer.UniqueSemantic.FILTER,
242+
1
240243
);
241244

242245
if ( results.size() > 1 ) {
@@ -364,12 +367,11 @@ public Object resolveIdToNaturalId(Object id, SharedSessionContractImplementor s
364367
jdbcSelect,
365368
jdbcParamBindings,
366369
new NoCallbackExecutionContext( session ),
367-
(row) -> {
368-
// because we select the natural-id we want to "reduce" the result
369-
assert row.length == 1;
370-
return row[0];
371-
},
372-
ListResultsConsumer.UniqueSemantic.FILTER
370+
// because we select the natural-id we want to "reduce" the result
371+
RowTransformerSingularReturnImpl.instance(),
372+
null,
373+
ListResultsConsumer.UniqueSemantic.FILTER,
374+
1
373375
);
374376

375377
switch ( results.size() ) {

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionElementLoaderByIndex.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ public Object load(Object key, Object index, SharedSessionContractImplementor se
150150
jdbcParameterBindings,
151151
new BaseExecutionContext( session ),
152152
RowTransformerStandardImpl.instance(),
153-
ListResultsConsumer.UniqueSemantic.FILTER
153+
null,
154+
ListResultsConsumer.UniqueSemantic.FILTER,
155+
1
154156
);
155157

156158
if ( list.isEmpty() ) {

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor sessio
177177
jdbcParameterBindings,
178178
new BaseExecutionContext( session ),
179179
RowTransformerDatabaseSnapshotImpl.instance(),
180-
ListResultsConsumer.UniqueSemantic.FILTER
180+
null,
181+
ListResultsConsumer.UniqueSemantic.FILTER,
182+
1
181183
);
182184

183185
final int size = list.size();

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityConcreteTypeLoader.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ public EntityMappingType getConcreteType(Object id, SharedSessionContractImpleme
9393
jdbcParamBindings,
9494
new BaseExecutionContext( session ),
9595
RowTransformerStandardImpl.instance(),
96-
ListResultsConsumer.UniqueSemantic.NONE
96+
null,
97+
ListResultsConsumer.UniqueSemantic.NONE,
98+
1
9799
);
98100

99101
if ( results.isEmpty() ) {

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,9 @@ public static <R,K> List<R> loadByArrayParameter(
243243
session
244244
),
245245
RowTransformerStandardImpl.instance(),
246-
ListResultsConsumer.UniqueSemantic.FILTER
246+
null,
247+
ListResultsConsumer.UniqueSemantic.FILTER,
248+
idsToInitialize.length
247249
);
248250
}
249251
}

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderArrayParam.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
4040
import org.hibernate.sql.exec.spi.JdbcParametersList;
4141
import org.hibernate.sql.results.internal.RowTransformerStandardImpl;
42-
import org.hibernate.sql.results.spi.ListResultsConsumer;
42+
import org.hibernate.sql.results.spi.ManagedResultConsumer;
4343

4444
import org.checkerframework.checker.nullness.qual.NonNull;
4545

@@ -190,12 +190,14 @@ protected <K> List<E> performOrderedMultiLoad(K[] ids, MultiIdLoadOptions loadOp
190190
jdbcParameterBindings
191191
);
192192

193-
session.getJdbcServices().getJdbcSelectExecutor().list(
193+
session.getJdbcServices().getJdbcSelectExecutor().executeQuery(
194194
jdbcSelectOperation,
195195
jdbcParameterBindings,
196196
new ExecutionContextWithSubselectFetchHandler( session, subSelectFetchableKeysHandler ),
197197
RowTransformerStandardImpl.instance(),
198-
ListResultsConsumer.UniqueSemantic.FILTER
198+
null,
199+
idsToLoadFromDatabase.size(),
200+
ManagedResultConsumer.INSTANCE
199201
);
200202

201203
for ( int i = 0; i < idsToLoadFromDatabaseResultIndexes.size(); i++ ) {

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderStandard.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,9 @@ private List<T> loadEntitiesById(
267267
jdbcParameterBindings,
268268
new ExecutionContextWithSubselectFetchHandler( session, subSelectFetchableKeysHandler ),
269269
RowTransformerStandardImpl.instance(),
270-
ListResultsConsumer.UniqueSemantic.FILTER
270+
null,
271+
ListResultsConsumer.UniqueSemantic.FILTER,
272+
idsInBatch.size()
271273
);
272274
}
273275

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadChunker.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.hibernate.sql.exec.spi.JdbcParametersList;
2020
import org.hibernate.sql.results.internal.RowTransformerStandardImpl;
2121
import org.hibernate.sql.results.spi.ListResultsConsumer;
22+
import org.hibernate.sql.results.spi.ManagedResultConsumer;
2223

2324
/**
2425
* When the number of ids to initialize exceeds a certain threshold, IN-predicate based
@@ -149,12 +150,14 @@ private void processChunk(
149150
return;
150151
}
151152

152-
session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
153+
session.getFactory().getJdbcServices().getJdbcSelectExecutor().executeQuery(
153154
jdbcSelect,
154155
jdbcParameterBindings,
155156
sqlExecutionContextCreator.createContext( jdbcParameterBindings, session ),
156157
RowTransformerStandardImpl.instance(),
157-
ListResultsConsumer.UniqueSemantic.FILTER
158+
null,
159+
nonNullCounter,
160+
ManagedResultConsumer.INSTANCE
158161
);
159162

160163
boundaryListener.chunkBoundaryNotification( startIndex, nonNullCounter );

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoadingBatcher.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
import java.util.List;
1111

1212
import org.hibernate.LockOptions;
13-
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
14-
import org.hibernate.engine.jdbc.spi.JdbcServices;
1513
import org.hibernate.engine.spi.LoadQueryInfluencers;
1614
import org.hibernate.engine.spi.SessionFactoryImplementor;
1715
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@@ -20,10 +18,8 @@
2018
import org.hibernate.loader.ast.spi.MultiNaturalIdLoadOptions;
2119
import org.hibernate.metamodel.mapping.EntityMappingType;
2220
import org.hibernate.metamodel.mapping.ModelPart;
23-
import org.hibernate.persister.entity.EntityPersister;
2421
import org.hibernate.query.spi.QueryOptions;
2522
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
26-
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
2723
import org.hibernate.sql.ast.tree.select.SelectStatement;
2824
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
2925
import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect;
@@ -97,6 +93,7 @@ public <E> List<E> multiLoad(Object[] naturalIdValues, MultiNaturalIdLoadOptions
9793
final JdbcParameterBindingsImpl jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
9894

9995
int offset = 0;
96+
int size = 0;
10097

10198
for ( int i = 0; i < naturalIdValues.length; i++ ) {
10299
final Object bindValue = keyValueResolver.resolveKeyToLoad( naturalIdValues[ i ], session );
@@ -108,14 +105,16 @@ public <E> List<E> multiLoad(Object[] naturalIdValues, MultiNaturalIdLoadOptions
108105
jdbcParameters,
109106
session
110107
);
108+
size++;
111109
}
112110

113111
if ( offset == jdbcParameters.size() ) {
114112
// we've hit the batch mark
115-
final List<E> batchResults = performLoad( jdbcParamBindings, session );
113+
final List<E> batchResults = performLoad( jdbcParamBindings, session, size );
116114
multiLoadResults.addAll( batchResults );
117115
jdbcParamBindings.clear();
118116
offset = 0;
117+
size = 0;
119118
}
120119
}
121120

@@ -129,15 +128,19 @@ public <E> List<E> multiLoad(Object[] naturalIdValues, MultiNaturalIdLoadOptions
129128
jdbcParameters,
130129
session
131130
);
131+
size++;
132132
}
133-
final List<E> batchResults = performLoad( jdbcParamBindings, session );
133+
final List<E> batchResults = performLoad( jdbcParamBindings, session, size );
134134
multiLoadResults.addAll( batchResults );
135135
}
136136

137137
return multiLoadResults;
138138
}
139139

140-
private <E> List<E> performLoad(JdbcParameterBindings jdbcParamBindings, SharedSessionContractImplementor session) {
140+
private <E> List<E> performLoad(
141+
JdbcParameterBindings jdbcParamBindings,
142+
SharedSessionContractImplementor session,
143+
int size) {
141144
final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler;
142145

143146
if ( session.getLoadQueryInfluencers().hasSubselectLoadableCollections( entityDescriptor.getEntityPersister() ) ) {
@@ -160,7 +163,9 @@ private <E> List<E> performLoad(JdbcParameterBindings jdbcParamBindings, SharedS
160163
jdbcParamBindings,
161164
new ExecutionContextWithSubselectFetchHandler( session, subSelectFetchableKeysHandler ),
162165
RowTransformerStandardImpl.instance(),
163-
ListResultsConsumer.UniqueSemantic.FILTER
166+
null,
167+
ListResultsConsumer.UniqueSemantic.FILTER,
168+
size
164169
);
165170
}
166171

0 commit comments

Comments
 (0)