Skip to content

Commit d2840f4

Browse files
committed
HHH-19336 - Proper implementation for JPA extended locking scope
HHH-19459 - LockScope, FollowOnLocking HHH-19501 - Session#lock w/ pessimistic locks for scopes HHH-19502 - Disallow SKIP_LOCKED with Session#lock HHH-19503 - Track a Dialect's level of support for locking joined tables
1 parent 2a852c6 commit d2840f4

File tree

15 files changed

+256
-46
lines changed

15 files changed

+256
-46
lines changed

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/AltibaseSqlAstTranslator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGro
113113
predicate = tableGroupJoin.getPredicate();
114114
}
115115
if ( predicate != null && !predicate.isEmpty() ) {
116-
renderTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
116+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
117117
}
118118
else {
119-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
119+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
120120
}
121121
}
122122

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ protected boolean needsRecursiveKeywordInWithClause() {
7575
}
7676

7777
@Override
78-
protected void renderTableReferenceJoins(TableGroup tableGroup, int swappedJoinIndex, boolean forceLeftJoin) {
78+
protected void renderTableReferenceJoins(TableGroup tableGroup, LockMode lockMode, int swappedJoinIndex, boolean forceLeftJoin) {
7979
// When we are in a recursive CTE, we can't render joins on DB2...
8080
// See https://modern-sql.com/feature/with-recursive/db2/error-345-state-42836
8181
if ( isInRecursiveQueryPart() ) {
@@ -102,7 +102,7 @@ protected void renderTableReferenceJoins(TableGroup tableGroup, int swappedJoinI
102102
}
103103
}
104104
else {
105-
super.renderTableReferenceJoins( tableGroup, swappedJoinIndex, forceLeftJoin );
105+
super.renderTableReferenceJoins( tableGroup, lockMode, swappedJoinIndex, forceLeftJoin );
106106
}
107107
}
108108

@@ -118,7 +118,7 @@ protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGro
118118
}
119119
appendSql( COMMA_SEPARATOR_CHAR );
120120

121-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
121+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
122122
if ( tableGroupJoin.getPredicate() != null && !tableGroupJoin.getPredicate().isEmpty() ) {
123123
addAdditionalWherePredicate( tableGroupJoin.getPredicate() );
124124
}

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,15 +165,15 @@ protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGro
165165
// We have to inject the lateral predicate into the sub-query
166166
final Predicate lateralPredicate = this.lateralPredicate;
167167
this.lateralPredicate = predicate;
168-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
168+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
169169
this.lateralPredicate = lateralPredicate;
170170
}
171171
else {
172-
renderTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
172+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
173173
}
174174
}
175175
else {
176-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
176+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
177177
}
178178
}
179179

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacySqlAstTranslator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,10 @@ protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGro
254254
predicate = tableGroupJoin.getPredicate();
255255
}
256256
if ( predicate != null && !predicate.isEmpty() ) {
257-
renderTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
257+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
258258
}
259259
else {
260-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
260+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
261261
}
262262
}
263263

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TimesTenSqlAstTranslator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGro
8181
predicate = tableGroupJoin.getPredicate();
8282
}
8383
if ( predicate != null && !predicate.isEmpty() ) {
84-
renderTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
84+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
8585
}
8686
else {
87-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
87+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
8888
}
8989
}
9090

hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2SqlAstTranslator.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ protected boolean needsRecursiveKeywordInWithClause() {
7575
}
7676

7777
@Override
78-
protected void renderTableReferenceJoins(TableGroup tableGroup, int swappedJoinIndex, boolean forceLeftJoin) {
78+
protected void renderTableReferenceJoins(TableGroup tableGroup, LockMode lockMode, int swappedJoinIndex, boolean forceLeftJoin) {
7979
// When we are in a recursive CTE, we can't render joins on DB2...
8080
// See https://modern-sql.com/feature/with-recursive/db2/error-345-state-42836
8181
if ( isInRecursiveQueryPart() ) {
@@ -94,15 +94,15 @@ protected void renderTableReferenceJoins(TableGroup tableGroup, int swappedJoinI
9494
}
9595
appendSql( COMMA_SEPARATOR_CHAR );
9696

97-
renderNamedTableReference( tableJoin.getJoinedTableReference(), LockMode.NONE );
97+
renderNamedTableReference( tableJoin.getJoinedTableReference(), lockMode );
9898

9999
if ( tableJoin.getPredicate() != null && !tableJoin.getPredicate().isEmpty() ) {
100100
addAdditionalWherePredicate( tableJoin.getPredicate() );
101101
}
102102
}
103103
}
104104
else {
105-
super.renderTableReferenceJoins( tableGroup, swappedJoinIndex, forceLeftJoin );
105+
super.renderTableReferenceJoins( tableGroup, lockMode, swappedJoinIndex, forceLeftJoin );
106106
}
107107
}
108108

@@ -118,7 +118,7 @@ protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGro
118118
}
119119
appendSql( COMMA_SEPARATOR_CHAR );
120120

121-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
121+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
122122
if ( tableGroupJoin.getPredicate() != null && !tableGroupJoin.getPredicate().isEmpty() ) {
123123
addAdditionalWherePredicate( tableGroupJoin.getPredicate() );
124124
}

hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SQLServerSqlAstTranslator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,15 @@ protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGro
166166
// We have to inject the lateral predicate into the sub-query
167167
final Predicate lateralPredicate = this.lateralPredicate;
168168
this.lateralPredicate = predicate;
169-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
169+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
170170
this.lateralPredicate = lateralPredicate;
171171
}
172172
else {
173-
renderTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
173+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
174174
}
175175
}
176176
else {
177-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
177+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
178178
}
179179
}
180180

hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseASESqlAstTranslator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,10 @@ protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGro
243243
predicate = tableGroupJoin.getPredicate();
244244
}
245245
if ( predicate != null && !predicate.isEmpty() ) {
246-
renderTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
246+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
247247
}
248248
else {
249-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
249+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
250250
}
251251
}
252252

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

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
3535
import org.hibernate.metamodel.mapping.MappingModelExpressible;
3636
import org.hibernate.metamodel.mapping.ModelPartContainer;
37+
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
3738
import org.hibernate.metamodel.mapping.SqlTypedMapping;
39+
import org.hibernate.metamodel.mapping.internal.BasicValuedCollectionPart;
3840
import org.hibernate.metamodel.model.domain.ReturnableType;
3941
import org.hibernate.persister.entity.EntityPersister;
4042
import org.hibernate.persister.internal.SqlFragmentPredicate;
@@ -5655,7 +5657,7 @@ protected void renderDmlTargetTableGroup(TableGroup tableGroup) {
56555657
assert getStatementStack().getCurrent() instanceof UpdateStatement updateStatement
56565658
&& updateStatement.getTargetTable() == tableGroup.getPrimaryTableReference();
56575659
appendSql( getDual() );
5658-
renderTableReferenceJoins( tableGroup );
5660+
renderTableReferenceJoins( tableGroup, LockMode.NONE );
56595661
processNestedTableGroupJoins( tableGroup, null );
56605662
processTableGroupJoins( tableGroup );
56615663
if ( tableGroup.getModelPart() instanceof EntityPersister persister ) {
@@ -5697,7 +5699,8 @@ protected void renderRootTableGroup(TableGroup tableGroup, List<TableGroupJoin>
56975699
addAdditionalWherePredicate( determineLateralEmulationPredicate( tableGroup ) );
56985700
}
56995701

5700-
renderTableReferenceJoins( tableGroup );
5702+
final LockMode lockMode = getEffectiveLockMode();
5703+
renderTableReferenceJoins( tableGroup, lockMode );
57015704
processNestedTableGroupJoins( tableGroup, tableGroupJoinCollector );
57025705
if ( tableGroupJoinCollector != null ) {
57035706
tableGroupJoinCollector.addAll( tableGroup.getTableGroupJoins() );
@@ -5713,7 +5716,14 @@ protected void renderRootTableGroup(TableGroup tableGroup, List<TableGroupJoin>
57135716
}
57145717
}
57155718

5716-
protected void renderTableGroup(TableGroup tableGroup, Predicate predicate, List<TableGroupJoin> tableGroupJoinCollector) {
5719+
/**
5720+
* Called to render the joined TableGroup from a {@linkplain TableGroupJoin}
5721+
* @param tableGroup The joined TableGroup
5722+
* @param tableGroupJoinCollector Collector for any nested TableGroupJoins
5723+
*/
5724+
protected void renderJoinedTableGroup(TableGroup tableGroup, Predicate predicate, List<TableGroupJoin> tableGroupJoinCollector) {
5725+
final LockMode lockModeToApply = determineJoinedTableGroupLockMode( tableGroup );
5726+
57175727
final boolean realTableGroup;
57185728
int swappedJoinIndex = -1;
57195729
boolean forceLeftJoin = false;
@@ -5746,7 +5756,7 @@ else if ( referenceJoinIndexForPredicateSwap == TableGroupHelper.NO_TABLE_GROUP_
57465756

57475757
// Render the table reference of the table reference join first
57485758
final TableReferenceJoin tableReferenceJoin = tableGroup.getTableReferenceJoins().get( swappedJoinIndex );
5749-
renderNamedTableReference( tableReferenceJoin.getJoinedTableReference(), LockMode.NONE );
5759+
renderNamedTableReference( tableReferenceJoin.getJoinedTableReference(), lockModeToApply );
57505760
// along with the predicate for the table group
57515761
if ( predicate != null ) {
57525762
appendSql( " on " );
@@ -5772,15 +5782,14 @@ else if ( referenceJoinIndexForPredicateSwap == TableGroupHelper.NO_TABLE_GROUP_
57725782
appendSql( OPEN_PARENTHESIS );
57735783
}
57745784

5775-
final LockMode effectiveLockMode = getEffectiveLockMode( tableGroup.getSourceAlias() );
5776-
final boolean usesLockHint = renderPrimaryTableReference( tableGroup, effectiveLockMode );
5785+
renderPrimaryTableReference( tableGroup, lockModeToApply );
57775786
final List<TableGroupJoin> tableGroupJoins;
57785787

57795788
if ( realTableGroup ) {
57805789
// For real table groups, we collect all normal table group joins within that table group
57815790
// The purpose of that is to render them in-order outside of the group/parenthesis
57825791
// This is necessary for at least Derby but is also a lot easier to read
5783-
renderTableReferenceJoins( tableGroup );
5792+
renderTableReferenceJoins( tableGroup, lockModeToApply );
57845793
if ( tableGroupJoinCollector == null ) {
57855794
tableGroupJoins = new ArrayList<>();
57865795
processNestedTableGroupJoins( tableGroup, tableGroupJoins );
@@ -5814,7 +5823,7 @@ else if ( referenceJoinIndexForPredicateSwap == TableGroupHelper.NO_TABLE_GROUP_
58145823
}
58155824

58165825
if ( !realTableGroup ) {
5817-
renderTableReferenceJoins( tableGroup, swappedJoinIndex, forceLeftJoin );
5826+
renderTableReferenceJoins( tableGroup, lockModeToApply, swappedJoinIndex, forceLeftJoin );
58185827
processNestedTableGroupJoins( tableGroup, tableGroupJoinCollector );
58195828
}
58205829
if ( tableGroupJoinCollector != null ) {
@@ -5838,6 +5847,32 @@ else if ( referenceJoinIndexForPredicateSwap == TableGroupHelper.NO_TABLE_GROUP_
58385847
}
58395848
}
58405849

5850+
private LockMode determineJoinedTableGroupLockMode(TableGroup joinedTableGroup) {
5851+
final Locking.Scope lockingScope = lockOptions == null ? Locking.Scope.ROOT_ONLY : lockOptions.getScope();
5852+
5853+
if ( lockingScope == Locking.Scope.ROOT_ONLY ) {
5854+
return LockMode.NONE;
5855+
}
5856+
5857+
if ( lockingScope == Locking.Scope.INCLUDE_FETCHES ) {
5858+
return joinedTableGroup.isFetched() ? getEffectiveLockMode() : LockMode.NONE;
5859+
}
5860+
5861+
if ( lockingScope == Locking.Scope.INCLUDE_COLLECTIONS ) {
5862+
// if the TableGroup is an owned (aka, non-inverse) collection, lock it
5863+
if ( joinedTableGroup.getModelPart() instanceof PluralAttributeMapping attrMapping ) {
5864+
if ( !attrMapping.getCollectionDescriptor().isInverse() ) {
5865+
// owned collection
5866+
if ( attrMapping.getElementDescriptor() instanceof BasicValuedCollectionPart ) {
5867+
return getEffectiveLockMode();
5868+
}
5869+
}
5870+
}
5871+
}
5872+
5873+
return LockMode.NONE;
5874+
}
5875+
58415876
protected boolean needsLocking(QuerySpec querySpec) {
58425877
return querySpec.getFromClause().queryTableGroups(
58435878
tableGroup -> {
@@ -6122,11 +6157,11 @@ protected void registerAffectedTable(String tableExpression) {
61226157
affectedTableNames.add( tableExpression );
61236158
}
61246159

6125-
protected void renderTableReferenceJoins(TableGroup tableGroup) {
6126-
renderTableReferenceJoins( tableGroup, -1, false );
6160+
protected void renderTableReferenceJoins(TableGroup tableGroup, LockMode lockMode) {
6161+
renderTableReferenceJoins( tableGroup, lockMode, -1, false );
61276162
}
61286163

6129-
protected void renderTableReferenceJoins(TableGroup tableGroup, int swappedJoinIndex, boolean forceLeftJoin) {
6164+
protected void renderTableReferenceJoins(TableGroup tableGroup, LockMode lockMode, int swappedJoinIndex, boolean forceLeftJoin) {
61306165
final List<TableReferenceJoin> joins = tableGroup.getTableReferenceJoins();
61316166
if ( joins == null || joins.isEmpty() ) {
61326167
return;
@@ -6154,7 +6189,7 @@ protected void renderTableReferenceJoins(TableGroup tableGroup, int swappedJoinI
61546189
}
61556190
appendSql( "join " );
61566191

6157-
renderNamedTableReference( tableJoin.getJoinedTableReference(), LockMode.NONE );
6192+
renderNamedTableReference( tableJoin.getJoinedTableReference(), lockMode );
61586193

61596194
if ( tableJoin.getPredicate() != null && !tableJoin.getPredicate().isEmpty() ) {
61606195
appendSql( " on " );
@@ -6220,10 +6255,10 @@ protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGro
62206255
predicate = tableGroupJoin.getPredicate();
62216256
}
62226257
if ( predicate != null && !predicate.isEmpty() ) {
6223-
renderTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
6258+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), predicate, tableGroupJoinCollector );
62246259
}
62256260
else {
6226-
renderTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
6261+
renderJoinedTableGroup( tableGroupJoin.getJoinedGroup(), null, tableGroupJoinCollector );
62276262
}
62286263
if ( lockingClauseStrategy != null ) {
62296264
lockingClauseStrategy.registerJoin( tableGroupJoin );
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.locking.options;
6+
7+
import jakarta.persistence.Column;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.Id;
10+
import jakarta.persistence.Basic;
11+
import jakarta.persistence.PrimaryKeyJoinColumn;
12+
import jakarta.persistence.SecondaryTable;
13+
import jakarta.persistence.Table;
14+
15+
/**
16+
* @author Steve Ebersole
17+
*/
18+
@Entity
19+
@Table(name = "details")
20+
@SecondaryTable(name = "supplementals", pkJoinColumns = @PrimaryKeyJoinColumn(name = "detail_fk"))
21+
public class Detail {
22+
@Id
23+
private Integer id;
24+
@Basic
25+
private String name;
26+
@Column(name = "txt", table = "supplementals")
27+
private String data;
28+
29+
protected Detail() {
30+
// for Hibernate use
31+
}
32+
33+
public Detail(Integer id, String name, String data) {
34+
this.id = id;
35+
this.name = name;
36+
this.data = data;
37+
}
38+
39+
public Integer getId() {
40+
return id;
41+
}
42+
43+
public String getName() {
44+
return name;
45+
}
46+
47+
public void setName(String name) {
48+
this.name = name;
49+
}
50+
51+
public String getData() {
52+
return data;
53+
}
54+
55+
public void setData(String data) {
56+
this.data = data;
57+
}
58+
}

hibernate-core/src/test/java/org/hibernate/orm/test/locking/options/Helper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public String getKeyColumnName() {
143143
}
144144
}
145145

146-
public static void checkSql(String sql, Dialect dialect, Table... tablesFetched) {
146+
public static void checkSql(String sql, Dialect dialect, TableInformation... tablesFetched) {
147147
// note: assume `tables` is in order
148148
final PessimisticLockStyle pessimisticLockStyle = dialect.getPessimisticLockStyle();
149149
if ( pessimisticLockStyle == PessimisticLockStyle.CLAUSE ) {
@@ -155,7 +155,7 @@ public static void checkSql(String sql, Dialect dialect, Table... tablesFetched)
155155
else if ( rowLockStrategy == RowLockStrategy.TABLE ) {
156156
final StringBuilder buffer = new StringBuilder();
157157
boolean firstPass = true;
158-
for ( Table table : tablesFetched ) {
158+
for ( TableInformation table : tablesFetched ) {
159159
if ( firstPass ) {
160160
firstPass = false;
161161
}
@@ -170,7 +170,7 @@ else if ( rowLockStrategy == RowLockStrategy.TABLE ) {
170170
assert rowLockStrategy == RowLockStrategy.COLUMN;
171171
final StringBuilder buffer = new StringBuilder();
172172
boolean firstPass = true;
173-
for ( Table table : tablesFetched ) {
173+
for ( TableInformation table : tablesFetched ) {
174174
if ( firstPass ) {
175175
firstPass = false;
176176
}
@@ -188,7 +188,7 @@ else if ( rowLockStrategy == RowLockStrategy.TABLE ) {
188188
else {
189189
// Transact SQL (mssql, sybase) "table hint"-style locking
190190
final LockOptions lockOptions = new LockOptions( LockMode.PESSIMISTIC_WRITE );
191-
for ( Table table : tablesFetched ) {
191+
for ( TableInformation table : tablesFetched ) {
192192
final String booksTableReference = dialect.appendLockHint( lockOptions, table.getTableAlias() );
193193
assertThat( sql ).contains( booksTableReference );
194194
}

0 commit comments

Comments
 (0)