Skip to content

Commit e9404ec

Browse files
committed
[#1613] Upgrade Hibernate ORM to 6.2.2.Final
Adapt changes in Hibernate ORM for: * HHH-16441 - Improve support for @batchsize * HHH-16466 - ARRAY parameter support for multi-key loads * HHH-16509 - Split parameter limit and IN element limit
1 parent ecca1ea commit e9404ec

31 files changed

+2191
-898
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ version = projectVersion
5353
// ./gradlew clean build -PhibernateOrmVersion=5.6.15-SNAPSHOT
5454
ext {
5555
if ( !project.hasProperty('hibernateOrmVersion') ) {
56-
hibernateOrmVersion = '6.2.1.Final'
56+
hibernateOrmVersion = '6.2.2.Final'
5757
}
5858
if ( !project.hasProperty( 'hibernateOrmGradlePluginVersion' ) ) {
5959
// Same as ORM as default
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.loader.ast.internal;
7+
8+
9+
import org.hibernate.collection.spi.PersistentCollection;
10+
import org.hibernate.engine.spi.CollectionEntry;
11+
import org.hibernate.engine.spi.CollectionKey;
12+
import org.hibernate.engine.spi.LoadQueryInfluencers;
13+
import org.hibernate.engine.spi.PersistenceContext;
14+
import org.hibernate.engine.spi.SessionFactoryImplementor;
15+
import org.hibernate.engine.spi.SharedSessionContractImplementor;
16+
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
17+
import org.hibernate.reactive.loader.ast.spi.ReactiveCollectionBatchLoader;
18+
import org.hibernate.sql.results.internal.ResultsHelper;
19+
20+
import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_DEBUG_ENABLED;
21+
import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER;
22+
23+
/**
24+
* @see org.hibernate.loader.ast.internal.AbstractCollectionBatchLoader
25+
*/
26+
public abstract class ReactiveAbstractCollectionBatchLoader implements ReactiveCollectionBatchLoader {
27+
private final int domainBatchSize;
28+
private final PluralAttributeMapping attributeMapping;
29+
private final LoadQueryInfluencers influencers;
30+
private final SessionFactoryImplementor sessionFactory;
31+
32+
private final int keyJdbcCount;
33+
34+
public ReactiveAbstractCollectionBatchLoader(
35+
int domainBatchSize,
36+
LoadQueryInfluencers influencers,
37+
PluralAttributeMapping attributeMapping,
38+
SessionFactoryImplementor sessionFactory) {
39+
this.domainBatchSize = domainBatchSize;
40+
this.attributeMapping = attributeMapping;
41+
42+
this.keyJdbcCount = attributeMapping.getJdbcTypeCount();
43+
this.sessionFactory = sessionFactory;
44+
this.influencers = influencers;
45+
}
46+
47+
@Override
48+
public int getDomainBatchSize() {
49+
return domainBatchSize;
50+
}
51+
52+
@Override
53+
public PluralAttributeMapping getLoadable() {
54+
return attributeMapping;
55+
}
56+
57+
public LoadQueryInfluencers getInfluencers() {
58+
return influencers;
59+
}
60+
61+
public SessionFactoryImplementor getSessionFactory() {
62+
return sessionFactory;
63+
}
64+
65+
public int getKeyJdbcCount() {
66+
return keyJdbcCount;
67+
}
68+
69+
protected void finishInitializingKey(
70+
Object key,
71+
SharedSessionContractImplementor session) {
72+
if ( key == null ) {
73+
return;
74+
}
75+
76+
if ( MULTI_KEY_LOAD_DEBUG_ENABLED ) {
77+
MULTI_KEY_LOAD_LOGGER.debugf( "Finishing initializing batch-fetched collection : %s.%s", attributeMapping.getNavigableRole().getFullPath(), key );
78+
}
79+
80+
final PersistenceContext persistenceContext = session.getPersistenceContext();
81+
final CollectionKey collectionKey = new CollectionKey( getLoadable().getCollectionDescriptor(), key );
82+
final PersistentCollection<?> collection = persistenceContext.getCollection( collectionKey );
83+
if ( !collection.wasInitialized() ) {
84+
final CollectionEntry entry = persistenceContext.getCollectionEntry( collection );
85+
collection.initializeEmptyCollection( entry.getLoadedPersister() );
86+
ResultsHelper.finalizeCollectionLoading(
87+
persistenceContext,
88+
entry.getLoadedPersister(),
89+
collection,
90+
collectionKey,
91+
true
92+
);
93+
}
94+
95+
}
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.loader.ast.internal;
7+
8+
import java.util.List;
9+
import java.util.Objects;
10+
import java.util.concurrent.CompletionStage;
11+
12+
import org.hibernate.engine.spi.SessionFactoryImplementor;
13+
import org.hibernate.event.spi.EventSource;
14+
import org.hibernate.loader.ast.internal.Preparable;
15+
import org.hibernate.loader.ast.spi.MultiIdLoadOptions;
16+
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
17+
import org.hibernate.metamodel.mapping.EntityMappingType;
18+
import org.hibernate.reactive.loader.ast.spi.ReactiveMultiIdEntityLoader;
19+
20+
/**
21+
* @see org.hibernate.loader.ast.internal.AbstractMultiIdEntityLoader
22+
*/
23+
public abstract class ReactiveAbstractMultiIdEntityLoader<T> implements ReactiveMultiIdEntityLoader<T>, Preparable {
24+
25+
private final EntityMappingType entityDescriptor;
26+
private final SessionFactoryImplementor sessionFactory;
27+
28+
private EntityIdentifierMapping identifierMapping;
29+
30+
public ReactiveAbstractMultiIdEntityLoader(EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) {
31+
this.entityDescriptor = entityDescriptor;
32+
this.sessionFactory = sessionFactory;
33+
}
34+
35+
@Override
36+
public void prepare() {
37+
identifierMapping = getLoadable().getIdentifierMapping();
38+
}
39+
40+
protected EntityMappingType getEntityDescriptor() {
41+
return entityDescriptor;
42+
}
43+
44+
protected SessionFactoryImplementor getSessionFactory() {
45+
return sessionFactory;
46+
}
47+
48+
public EntityIdentifierMapping getIdentifierMapping() {
49+
return identifierMapping;
50+
}
51+
52+
@Override
53+
public EntityMappingType getLoadable() {
54+
return getEntityDescriptor();
55+
}
56+
57+
@Override
58+
public final <K> CompletionStage<List<T>> load(K[] ids, MultiIdLoadOptions loadOptions, EventSource session) {
59+
Objects.requireNonNull( ids );
60+
61+
return loadOptions.isOrderReturnEnabled()
62+
? performOrderedMultiLoad( ids, loadOptions, session )
63+
: performUnorderedMultiLoad( ids, loadOptions, session );
64+
}
65+
66+
protected abstract <K> CompletionStage<List<T>> performOrderedMultiLoad(K[] ids, MultiIdLoadOptions loadOptions, EventSource session);
67+
68+
protected abstract <K> CompletionStage<List<T>> performUnorderedMultiLoad(K[] ids, MultiIdLoadOptions loadOptions, EventSource session);
69+
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.loader.ast.internal;
7+
8+
import java.util.Map;
9+
10+
import org.hibernate.boot.registry.StandardServiceInitiator;
11+
import org.hibernate.loader.ast.spi.BatchLoaderFactory;
12+
import org.hibernate.service.spi.ServiceRegistryImplementor;
13+
14+
/**
15+
* Initiator for {@link ReactiveStandardBatchLoaderFactory}
16+
*/
17+
public class ReactiveBatchLoaderFactoryInitiator implements StandardServiceInitiator<BatchLoaderFactory> {
18+
/**
19+
* Singleton access
20+
*/
21+
public static final ReactiveBatchLoaderFactoryInitiator INSTANCE = new ReactiveBatchLoaderFactoryInitiator();
22+
23+
@Override
24+
public BatchLoaderFactory initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) {
25+
return new ReactiveStandardBatchLoaderFactory();
26+
}
27+
28+
@Override
29+
public Class<BatchLoaderFactory> getServiceInitiated() {
30+
return BatchLoaderFactory.class;
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.loader.ast.internal;
7+
8+
import java.lang.reflect.Array;
9+
import java.util.Collections;
10+
import java.util.concurrent.CompletionStage;
11+
12+
import org.hibernate.LockOptions;
13+
import org.hibernate.collection.spi.PersistentCollection;
14+
import org.hibernate.engine.spi.CollectionKey;
15+
import org.hibernate.engine.spi.LoadQueryInfluencers;
16+
import org.hibernate.engine.spi.SessionFactoryImplementor;
17+
import org.hibernate.engine.spi.SharedSessionContractImplementor;
18+
import org.hibernate.engine.spi.SubselectFetch;
19+
import org.hibernate.loader.ast.internal.LoaderSelectBuilder;
20+
import org.hibernate.loader.ast.internal.MultiKeyLoadHelper;
21+
import org.hibernate.loader.ast.spi.SqlArrayMultiKeyLoader;
22+
import org.hibernate.metamodel.mapping.JdbcMapping;
23+
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
24+
import org.hibernate.metamodel.mapping.internal.SimpleForeignKeyDescriptor;
25+
import org.hibernate.query.spi.QueryOptions;
26+
import org.hibernate.reactive.sql.exec.internal.StandardReactiveSelectExecutor;
27+
import org.hibernate.reactive.sql.results.spi.ReactiveListResultsConsumer;
28+
import org.hibernate.reactive.util.impl.CompletionStages;
29+
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
30+
import org.hibernate.sql.ast.tree.select.SelectStatement;
31+
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
32+
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
33+
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
34+
import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect;
35+
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
36+
import org.hibernate.sql.results.internal.RowTransformerStandardImpl;
37+
import org.hibernate.type.BasicType;
38+
39+
import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_DEBUG_ENABLED;
40+
import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LOAD_LOGGER;
41+
42+
/**
43+
* @see org.hibernate.loader.ast.internal.CollectionBatchLoaderArrayParam
44+
*/
45+
public class ReactiveCollectionBatchLoaderArrayParam extends ReactiveAbstractCollectionBatchLoader
46+
implements SqlArrayMultiKeyLoader {
47+
48+
private final Class<?> arrayElementType;
49+
private final JdbcMapping arrayJdbcMapping;
50+
private final JdbcParameter jdbcParameter;
51+
private final SelectStatement sqlSelect;
52+
private final JdbcOperationQuerySelect jdbcSelectOperation;
53+
54+
public ReactiveCollectionBatchLoaderArrayParam(
55+
int domainBatchSize,
56+
LoadQueryInfluencers loadQueryInfluencers,
57+
PluralAttributeMapping attributeMapping,
58+
SessionFactoryImplementor sessionFactory) {
59+
super( domainBatchSize, loadQueryInfluencers, attributeMapping, sessionFactory );
60+
61+
if ( MULTI_KEY_LOAD_DEBUG_ENABLED ) {
62+
MULTI_KEY_LOAD_LOGGER.debugf(
63+
"Using ARRAY batch fetching strategy for collection `%s` : %s",
64+
attributeMapping.getNavigableRole().getFullPath(),
65+
domainBatchSize
66+
);
67+
}
68+
69+
final SimpleForeignKeyDescriptor keyDescriptor = (SimpleForeignKeyDescriptor) getLoadable().getKeyDescriptor();
70+
71+
arrayElementType = keyDescriptor.getJavaType().getJavaTypeClass();
72+
Class<?> arrayClass = Array.newInstance( arrayElementType, 0 ).getClass();
73+
74+
final BasicType<?> arrayBasicType = getSessionFactory().getTypeConfiguration()
75+
.getBasicTypeRegistry()
76+
.getRegisteredType( arrayClass );
77+
arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping(
78+
arrayBasicType,
79+
keyDescriptor.getJdbcMapping(),
80+
arrayClass,
81+
getSessionFactory()
82+
);
83+
84+
jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping );
85+
sqlSelect = LoaderSelectBuilder.createSelectBySingleArrayParameter(
86+
getLoadable(),
87+
keyDescriptor.getKeyPart(),
88+
getInfluencers(),
89+
LockOptions.NONE,
90+
jdbcParameter,
91+
getSessionFactory()
92+
);
93+
94+
jdbcSelectOperation = getSessionFactory().getJdbcServices()
95+
.getJdbcEnvironment()
96+
.getSqlAstTranslatorFactory()
97+
.buildSelectTranslator( getSessionFactory(), sqlSelect )
98+
.translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE );
99+
}
100+
101+
@Override
102+
public CompletionStage<PersistentCollection<?>> reactiveLoad(Object key, SharedSessionContractImplementor session) {
103+
if ( MULTI_KEY_LOAD_DEBUG_ENABLED ) {
104+
MULTI_KEY_LOAD_LOGGER.debugf(
105+
"Batch loading entity `%s#%s`",
106+
getLoadable().getNavigableRole().getFullPath(),
107+
key
108+
);
109+
}
110+
111+
final Object[] keysToInitialize = resolveKeysToInitialize( key, session );
112+
return initializeKeys( keysToInitialize, session )
113+
.thenApply( v -> {
114+
for ( int i = 0; i < keysToInitialize.length; i++ ) {
115+
finishInitializingKey( keysToInitialize[i], session );
116+
}
117+
118+
final CollectionKey collectionKey = new CollectionKey(
119+
getLoadable().getCollectionDescriptor(),
120+
key
121+
);
122+
return session.getPersistenceContext().getCollection( collectionKey );
123+
} );
124+
}
125+
126+
private Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImplementor session) {
127+
final Object[] keysToInitialize = (Object[]) Array.newInstance( arrayElementType, getDomainBatchSize() );
128+
session.getPersistenceContextInternal().getBatchFetchQueue().collectBatchLoadableCollectionKeys(
129+
getDomainBatchSize(),
130+
(index, value) -> keysToInitialize[index] = value,
131+
keyBeingLoaded,
132+
getLoadable()
133+
);
134+
return keysToInitialize;
135+
}
136+
137+
private CompletionStage<Void> initializeKeys(Object[] keysToInitialize, SharedSessionContractImplementor session) {
138+
assert jdbcSelectOperation != null;
139+
assert jdbcParameter != null;
140+
141+
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( 1 );
142+
jdbcParameterBindings
143+
.addBinding( jdbcParameter, new JdbcParameterBindingImpl( arrayJdbcMapping, keysToInitialize ) );
144+
145+
final SubselectFetch.RegistrationHandler subSelectFetchableKeysHandler = SubselectFetch.createRegistrationHandler(
146+
session.getPersistenceContext().getBatchFetchQueue(),
147+
sqlSelect,
148+
Collections.singletonList( jdbcParameter ),
149+
jdbcParameterBindings
150+
);
151+
152+
return StandardReactiveSelectExecutor.INSTANCE.list(
153+
jdbcSelectOperation,
154+
jdbcParameterBindings,
155+
new SingleIdExecutionContext(
156+
null,
157+
null,
158+
null,
159+
LockOptions.NONE,
160+
subSelectFetchableKeysHandler,
161+
session
162+
),
163+
RowTransformerStandardImpl.instance(),
164+
ReactiveListResultsConsumer.UniqueSemantic.FILTER
165+
).thenCompose( CompletionStages::voidFuture );
166+
}
167+
168+
public void prepare() {
169+
}
170+
171+
}

0 commit comments

Comments
 (0)