Skip to content

Commit d364f68

Browse files
committed
Add JdbcSelectWithActionsBuilder and other changes to adapt Hibernate Reactive to the cvhanges intorduced by HHH-19513
1 parent 007a349 commit d364f68

File tree

8 files changed

+314
-137
lines changed

8 files changed

+314
-137
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
3535
import org.hibernate.service.spi.ServiceRegistryImplementor;
3636
import org.hibernate.sql.ast.spi.ParameterMarkerStrategy;
37+
import org.hibernate.sql.exec.internal.JdbcSelectWithActions;
38+
import org.hibernate.sql.exec.spi.JdbcSelectWithActionsBuilder;
3739
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducerProvider;
3840
import org.hibernate.stat.spi.StatisticsImplementor;
3941
import org.hibernate.generator.Generator;
@@ -315,4 +317,9 @@ default <T> RootGraphImplementor<T> createEntityGraph(Class<T> entityType) {
315317
*/
316318
String bestGuessEntityName(Object object);
317319

320+
@Incubating
321+
default JdbcSelectWithActionsBuilder getJdbcSelectWithActionsBuilder(){
322+
return new JdbcSelectWithActions.Builder();
323+
}
324+
318325
}

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2201,7 +2201,8 @@ protected LockingStrategy generateLocker(LockMode lockMode, Locking.Scope lockSc
22012201
return getDialect().getLockingStrategy( this, lockMode, lockScope );
22022202
}
22032203

2204-
private LockingStrategy getLocker(LockMode lockMode, Locking.Scope lockScope) {
2204+
// Used by Hibernate Reactive
2205+
protected LockingStrategy getLocker(LockMode lockMode, Locking.Scope lockScope) {
22052206
return lockScope != Locking.Scope.ROOT_ONLY
22062207
// be sure to not use the cached form if any form of extended locking is requested
22072208
? generateLocker( lockMode, lockScope )

hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import org.hibernate.dialect.Dialect;
1515
import org.hibernate.dialect.DmlTargetColumnQualifierSupport;
1616
import org.hibernate.dialect.SelectItemReferenceStrategy;
17-
import org.hibernate.dialect.lock.spi.LockTimeoutType;
1817
import org.hibernate.dialect.lock.spi.LockingSupport;
1918
import org.hibernate.engine.jdbc.Size;
2019
import org.hibernate.engine.jdbc.spi.JdbcServices;
@@ -177,11 +176,7 @@
177176
import org.hibernate.sql.exec.internal.JdbcOperationQuerySelect;
178177
import org.hibernate.sql.exec.internal.JdbcOperationQueryUpdate;
179178
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
180-
import org.hibernate.sql.exec.internal.JdbcSelectWithActions;
181-
import org.hibernate.sql.exec.internal.LockTimeoutHandler;
182179
import org.hibernate.sql.exec.internal.SqlTypedMappingJdbcParameter;
183-
import org.hibernate.sql.exec.internal.lock.CollectionLockingAction;
184-
import org.hibernate.sql.exec.internal.lock.FollowOnLockingAction;
185180
import org.hibernate.sql.exec.spi.ExecutionContext;
186181
import org.hibernate.sql.exec.spi.JdbcLockStrategy;
187182
import org.hibernate.sql.exec.spi.JdbcOperation;
@@ -893,26 +888,17 @@ protected JdbcSelect translateSelect(SelectStatement selectStatement) {
893888

894889
final LockingSupport lockingSupport = getDialect().getLockingSupport();
895890
final LockingSupport.Metadata lockingSupportMetadata = lockingSupport.getMetadata();
896-
897-
final JdbcSelectWithActions.Builder builder = new JdbcSelectWithActions.Builder( jdbcSelect );
898-
899-
final LockTimeoutType lockTimeoutType = lockingSupportMetadata.getLockTimeoutType( lockOptions.getTimeout() );
900-
if ( lockTimeoutType == LockTimeoutType.CONNECTION ) {
901-
builder.addSecondaryActionPair( new LockTimeoutHandler(
902-
lockOptions.getTimeout(),
903-
lockingSupport.getConnectionLockTimeoutStrategy()
904-
) );
905-
}
906-
907891
final LockStrategy lockStrategy = determineLockingStrategy( lockingTarget, lockOptions.getFollowOnStrategy() );
908-
if ( lockStrategy == LockStrategy.FOLLOW_ON ) {
909-
FollowOnLockingAction.apply( lockOptions, lockingTarget, lockingClauseStrategy, builder );
910-
}
911-
else if ( lockOptions.getScope() == Locking.Scope.INCLUDE_COLLECTIONS ) {
912-
CollectionLockingAction.apply( lockOptions, lockingTarget, builder );
913-
}
914892

915-
return builder.build();
893+
return getSessionFactory().getJdbcSelectWithActionsBuilder()
894+
.setPrimaryAction( jdbcSelect )
895+
.setLockTimeoutType( lockingSupportMetadata.getLockTimeoutType( lockOptions.getTimeout() ) )
896+
.setLockingSupport( lockingSupport )
897+
.setLockOptions( lockOptions )
898+
.setLockingTarget( lockingTarget )
899+
.setLockingClauseStrategy( lockingClauseStrategy )
900+
.setIsFollowOnLockStrategy( lockStrategy == LockStrategy.FOLLOW_ON )
901+
.build();
916902
}
917903

918904
private JdbcValuesMappingProducer buildJdbcValuesMappingProducer(SelectStatement selectStatement) {

hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcSelectWithActions.java

Lines changed: 100 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,25 @@
55
package org.hibernate.sql.exec.internal;
66

77
import org.checkerframework.checker.nullness.qual.Nullable;
8+
import org.hibernate.LockOptions;
9+
import org.hibernate.Locking;
10+
import org.hibernate.dialect.lock.spi.LockTimeoutType;
11+
import org.hibernate.dialect.lock.spi.LockingSupport;
812
import org.hibernate.internal.util.collections.CollectionHelper;
913
import org.hibernate.query.spi.QueryOptions;
14+
import org.hibernate.sql.ast.spi.LockingClauseStrategy;
1015
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
16+
import org.hibernate.sql.ast.tree.select.QuerySpec;
17+
import org.hibernate.sql.exec.internal.lock.CollectionLockingAction;
18+
import org.hibernate.sql.exec.internal.lock.FollowOnLockingAction;
1119
import org.hibernate.sql.exec.spi.ExecutionContext;
1220
import org.hibernate.sql.exec.spi.JdbcLockStrategy;
1321
import org.hibernate.sql.exec.spi.JdbcOperationQuery;
1422
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
1523
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
1624
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
1725
import org.hibernate.sql.exec.spi.JdbcSelect;
26+
import org.hibernate.sql.exec.spi.JdbcSelectWithActionsBuilder;
1827
import org.hibernate.sql.exec.spi.LoadedValuesCollector;
1928
import org.hibernate.sql.exec.spi.PostAction;
2029
import org.hibernate.sql.exec.spi.PreAction;
@@ -35,9 +44,12 @@
3544
public class JdbcSelectWithActions implements JdbcOperationQuery, JdbcSelect {
3645
private final JdbcOperationQuerySelect primaryOperation;
3746

38-
private final LoadedValuesCollector loadedValuesCollector;
39-
private final PreAction[] preActions;
40-
private final PostAction[] postActions;
47+
// Used by Hibernate Reactive
48+
protected final LoadedValuesCollector loadedValuesCollector;
49+
// Used by Hibernate Reactive
50+
protected final PreAction[] preActions;
51+
// Used by Hibernate Reactive
52+
protected final PostAction[] postActions;
4153

4254
public JdbcSelectWithActions(
4355
JdbcOperationQuerySelect primaryOperation,
@@ -149,24 +161,84 @@ public boolean isCompatibleWith(JdbcParameterBindings jdbcParameterBindings, Que
149161
return primaryOperation.isCompatibleWith( jdbcParameterBindings, queryOptions );
150162
}
151163

152-
public static class Builder {
153-
private final JdbcOperationQuerySelect primaryAction;
154-
164+
public static class Builder implements JdbcSelectWithActionsBuilder {
165+
private JdbcOperationQuerySelect primaryAction;
155166
private LoadedValuesCollector loadedValuesCollector;
156167
protected List<PreAction> preActions;
157168
protected List<PostAction> postActions;
158-
159-
public Builder(JdbcOperationQuerySelect primaryAction) {
160-
this.primaryAction = primaryAction;
169+
protected LockTimeoutType lockTimeoutType;
170+
protected LockingSupport lockingSupport;
171+
protected LockOptions lockOptions;
172+
protected QuerySpec lockingTarget;
173+
protected LockingClauseStrategy lockingClauseStrategy;
174+
boolean isFollonOnLockStrategy;
175+
176+
@Override
177+
public Builder setPrimaryAction(JdbcSelect primaryAction){
178+
assert primaryAction instanceof JdbcOperationQuerySelect;
179+
this.primaryAction = (JdbcOperationQuerySelect) primaryAction;
180+
return this;
161181
}
162182

163183
@SuppressWarnings("UnusedReturnValue")
184+
@Override
164185
public Builder setLoadedValuesCollector(LoadedValuesCollector loadedValuesCollector) {
165186
this.loadedValuesCollector = loadedValuesCollector;
166187
return this;
167188
}
168189

190+
@Override
191+
public Builder setLockTimeoutType(LockTimeoutType lockTimeoutType){
192+
this.lockTimeoutType = lockTimeoutType;
193+
return this;
194+
}
195+
196+
@Override
197+
public Builder setLockingSupport(LockingSupport lockingSupport){
198+
this.lockingSupport = lockingSupport;
199+
return this;
200+
}
201+
202+
@Override
203+
public Builder setLockOptions(LockOptions lockOptions){
204+
this.lockOptions = lockOptions;
205+
return this;
206+
}
207+
208+
@Override
209+
public Builder setLockingTarget(QuerySpec lockingTarget){
210+
this.lockingTarget = lockingTarget;
211+
return this;
212+
}
213+
214+
@Override
215+
public Builder setLockingClauseStrategy(LockingClauseStrategy lockingClauseStrategy){
216+
this.lockingClauseStrategy = lockingClauseStrategy;
217+
return this;
218+
}
219+
220+
@Override
221+
public Builder setIsFollowOnLockStrategy(boolean isFollonOnLockStrategy){
222+
this.isFollonOnLockStrategy = isFollonOnLockStrategy;
223+
return this;
224+
}
225+
226+
@Override
169227
public JdbcSelect build() {
228+
if ( lockTimeoutType == LockTimeoutType.CONNECTION ) {
229+
addSecondaryActionPair(
230+
new LockTimeoutHandler(
231+
lockOptions.getTimeout(),
232+
lockingSupport.getConnectionLockTimeoutStrategy()
233+
)
234+
);
235+
}
236+
if ( isFollonOnLockStrategy ) {
237+
FollowOnLockingAction.apply( lockOptions, lockingTarget, lockingClauseStrategy, this );
238+
}
239+
else if ( lockOptions.getScope() == Locking.Scope.INCLUDE_COLLECTIONS ) {
240+
CollectionLockingAction.apply( lockOptions, lockingTarget, this );
241+
}
170242
if ( preActions == null && postActions == null ) {
171243
assert loadedValuesCollector == null;
172244
return primaryAction;
@@ -182,6 +254,7 @@ public JdbcSelect build() {
182254
*
183255
* @return {@code this}, for method chaining.
184256
*/
257+
@Override
185258
public Builder appendPreAction(PreAction... actions) {
186259
if ( preActions == null ) {
187260
preActions = new ArrayList<>();
@@ -195,6 +268,7 @@ public Builder appendPreAction(PreAction... actions) {
195268
*
196269
* @return {@code this}, for method chaining.
197270
*/
271+
@Override
198272
public Builder prependPreAction(PreAction... actions) {
199273
if ( preActions == null ) {
200274
preActions = new ArrayList<>();
@@ -209,6 +283,7 @@ public Builder prependPreAction(PreAction... actions) {
209283
*
210284
* @return {@code this}, for method chaining.
211285
*/
286+
@Override
212287
public Builder appendPostAction(PostAction... actions) {
213288
if ( postActions == null ) {
214289
postActions = new ArrayList<>();
@@ -222,6 +297,7 @@ public Builder appendPostAction(PostAction... actions) {
222297
*
223298
* @return {@code this}, for method chaining.
224299
*/
300+
@Override
225301
public Builder prependPostAction(PostAction... actions) {
226302
if ( postActions == null ) {
227303
postActions = new ArrayList<>();
@@ -243,6 +319,7 @@ public Builder prependPostAction(PostAction... actions) {
243319
*
244320
* @return {@code this}, for method chaining.
245321
*/
322+
@Override
246323
public Builder addSecondaryActionPair(SecondaryAction action) {
247324
return addSecondaryActionPair( (PreAction) action, (PostAction) action );
248325
}
@@ -255,24 +332,27 @@ public Builder addSecondaryActionPair(SecondaryAction action) {
255332
*
256333
* @return {@code this}, for method chaining.
257334
*/
335+
@Override
258336
public Builder addSecondaryActionPair(PreAction preAction, PostAction postAction) {
259337
prependPreAction( preAction );
260338
appendPostAction( postAction );
261339
return this;
262340
}
263341

264-
private static PreAction[] toPreActionArray(List<PreAction> actions) {
265-
if ( CollectionHelper.isEmpty( actions ) ) {
266-
return null;
267-
}
268-
return actions.toArray( new PreAction[0] );
342+
// Used by Hibernate Reactive
343+
static PreAction[] toPreActionArray(List<PreAction> actions) {
344+
if ( CollectionHelper.isEmpty( actions ) ) {
345+
return null;
269346
}
270-
271-
private static PostAction[] toPostActionArray(List<PostAction> actions) {
272-
if ( CollectionHelper.isEmpty( actions ) ) {
273-
return null;
274-
}
275-
return actions.toArray( new PostAction[0] );
347+
return actions.toArray( new PreAction[0] );
348+
}
349+
// Used by Hibernate Reactive
350+
static PostAction[] toPostActionArray(List<PostAction> actions) {
351+
if ( CollectionHelper.isEmpty( actions ) ) {
352+
return null;
276353
}
354+
return actions.toArray( new PostAction[0] );
355+
}
356+
277357
}
278358
}

hibernate-core/src/main/java/org/hibernate/sql/exec/internal/lock/CollectionLockingAction.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import org.hibernate.sql.ast.tree.from.FromClause;
1919
import org.hibernate.sql.ast.tree.from.TableGroup;
2020
import org.hibernate.sql.ast.tree.select.QuerySpec;
21-
import org.hibernate.sql.exec.internal.JdbcSelectWithActions;
2221
import org.hibernate.sql.exec.spi.ExecutionContext;
22+
import org.hibernate.sql.exec.spi.JdbcSelectWithActionsBuilder;
2323
import org.hibernate.sql.exec.spi.LoadedValuesCollector;
2424
import org.hibernate.sql.exec.spi.PostAction;
2525
import org.hibernate.sql.exec.spi.StatementAccess;
@@ -40,11 +40,15 @@
4040
* @author Steve Ebersole
4141
*/
4242
public class CollectionLockingAction implements PostAction {
43-
private final LoadedValuesCollectorImpl loadedValuesCollector;
44-
private final LockMode lockMode;
45-
private final Timeout lockTimeout;
46-
47-
private CollectionLockingAction(
43+
// Used by Hibernate Reactive
44+
protected final LoadedValuesCollectorImpl loadedValuesCollector;
45+
// Used by Hibernate Reactive
46+
protected final LockMode lockMode;
47+
// Used by Hibernate Reactive
48+
protected final Timeout lockTimeout;
49+
50+
// Used by Hibernate Reactive
51+
protected CollectionLockingAction(
4852
LoadedValuesCollectorImpl loadedValuesCollector,
4953
LockMode lockMode,
5054
Timeout lockTimeout) {
@@ -56,7 +60,7 @@ private CollectionLockingAction(
5660
public static void apply(
5761
LockOptions lockOptions,
5862
QuerySpec lockingTarget,
59-
JdbcSelectWithActions.Builder jdbcSelectBuilder) {
63+
JdbcSelectWithActionsBuilder jdbcSelectBuilder) {
6064
assert lockOptions.getScope() == Locking.Scope.INCLUDE_COLLECTIONS;
6165

6266
final var loadedValuesCollector = resolveLoadedValuesCollector( lockingTarget.getFromClause() );
@@ -78,6 +82,11 @@ public void performPostAction(
7882
StatementAccess jdbcStatementAccess,
7983
Connection jdbcConnection,
8084
ExecutionContext executionContext) {
85+
performPostAction( executionContext );
86+
}
87+
88+
// Used by Hibernate Reactive
89+
protected void performPostAction(ExecutionContext executionContext) {
8190
LockingHelper.logLoadedValues( loadedValuesCollector );
8291

8392
final var session = executionContext.getSession();
@@ -130,7 +139,8 @@ public void performPostAction(
130139
}
131140
}
132141

133-
private static LoadedValuesCollectorImpl resolveLoadedValuesCollector(FromClause fromClause) {
142+
// Used by Hibernate Reactive
143+
protected static LoadedValuesCollectorImpl resolveLoadedValuesCollector(FromClause fromClause) {
134144
final var fromClauseRoots = fromClause.getRoots();
135145
if ( fromClauseRoots.size() == 1 ) {
136146
return new LoadedValuesCollectorImpl(
@@ -144,7 +154,8 @@ private static LoadedValuesCollectorImpl resolveLoadedValuesCollector(FromClause
144154
}
145155
}
146156

147-
private static Map<EntityMappingType, List<EntityKey>> segmentLoadedValues(LoadedValuesCollector loadedValuesCollector) {
157+
// Used by Hibernate Reactive
158+
protected static Map<EntityMappingType, List<EntityKey>> segmentLoadedValues(LoadedValuesCollector loadedValuesCollector) {
148159
final Map<EntityMappingType, List<EntityKey>> map = new IdentityHashMap<>();
149160
LockingHelper.segmentLoadedValues( loadedValuesCollector.getCollectedRootEntities(), map );
150161
LockingHelper.segmentLoadedValues( loadedValuesCollector.getCollectedNonRootEntities(), map );
@@ -155,7 +166,8 @@ private static Map<EntityMappingType, List<EntityKey>> segmentLoadedValues(Loade
155166
return map;
156167
}
157168

158-
private static class LoadedValuesCollectorImpl implements LoadedValuesCollector {
169+
// Used by Hibernate Reactive
170+
protected static class LoadedValuesCollectorImpl implements LoadedValuesCollector {
159171
private final List<NavigablePath> rootPaths;
160172

161173
private List<LoadedEntityRegistration> rootEntitiesToLock;

0 commit comments

Comments
 (0)