Skip to content

Commit b2ec9c1

Browse files
committed
Also handle join tables for RowLockStrategy.COLUMN
1 parent 6e3feaa commit b2ec9c1

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

hibernate-core/src/main/java/org/hibernate/sql/ast/internal/StandardLockingClauseStrategy.java

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,23 @@
1212
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
1313
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
1414
import org.hibernate.metamodel.mapping.ModelPart;
15+
import org.hibernate.metamodel.mapping.ModelPartContainer;
1516
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
17+
import org.hibernate.metamodel.mapping.TableDetails;
1618
import org.hibernate.metamodel.mapping.ValuedModelPart;
1719
import org.hibernate.metamodel.mapping.internal.BasicValuedCollectionPart;
1820
import org.hibernate.persister.entity.EntityPersister;
21+
import org.hibernate.persister.entity.mutation.EntityTableMapping;
1922
import org.hibernate.sql.ast.SqlAstJoinType;
2023
import org.hibernate.sql.ast.spi.LockingClauseStrategy;
2124
import org.hibernate.sql.ast.spi.SqlAppender;
25+
import org.hibernate.sql.ast.tree.from.NamedTableReference;
2226
import org.hibernate.sql.ast.tree.from.TableGroup;
2327
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
2428
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
29+
import org.hibernate.sql.model.TableMapping;
2530

2631
import java.util.ArrayList;
27-
import java.util.Collections;
2832
import java.util.HashSet;
2933
import java.util.LinkedHashSet;
3034
import java.util.List;
@@ -212,21 +216,54 @@ private void addTableAliases(TableGroup tableGroup, List<String> lockItems) {
212216
}
213217

214218
private void addColumnRefs(TableGroup tableGroup, List<String> lockItems) {
215-
Collections.addAll( lockItems, determineKeyColumnRefs( tableGroup ) );
216-
}
217-
218-
private String[] determineKeyColumnRefs(TableGroup tableGroup) {
219219
final String[] keyColumns = determineKeyColumnNames( tableGroup.getModelPart() );
220-
final String[] result = new String[keyColumns.length];
221220
final String tableAlias = tableGroup.getPrimaryTableReference().getIdentificationVariable();
222221
for ( int i = 0; i < keyColumns.length; i++ ) {
223222
// NOTE: in some tests with Oracle, the qualifiers are being applied twice;
224223
// still need to track that down. possibly, unexpected calls to
225224
// `Dialect#applyLocksToSql`?
226225
assert !keyColumns[i].contains( "." );
227-
result[i] = tableAlias + "." + keyColumns[i];
226+
lockItems.add( tableAlias + "." + keyColumns[i] );
227+
}
228+
229+
final List<TableReferenceJoin> tableReferenceJoins = tableGroup.getTableReferenceJoins();
230+
if ( CollectionHelper.isNotEmpty( tableReferenceJoins ) ) {
231+
final EntityPersister entityPersister = determineEntityPersister( tableGroup.getModelPart() );
232+
for ( int i = 0; i < tableReferenceJoins.size(); i++ ) {
233+
final TableReferenceJoin tableReferenceJoin = tableReferenceJoins.get( i );
234+
final NamedTableReference joinedTableReference = tableReferenceJoin.getJoinedTableReference();
235+
final String tableJoinAlias = joinedTableReference.getIdentificationVariable();
236+
final TableMapping tableMapping = determineTableMapping( entityPersister, tableReferenceJoin );
237+
for ( TableDetails.KeyColumn keyColumn : tableMapping.getKeyDetails().getKeyColumns() ) {
238+
lockItems.add( tableJoinAlias + "." + keyColumn.getColumnName() );
239+
}
240+
}
241+
}
242+
}
243+
244+
private TableMapping determineTableMapping(EntityPersister entityPersister, TableReferenceJoin tableReferenceJoin) {
245+
final NamedTableReference joinedTableReference = tableReferenceJoin.getJoinedTableReference();
246+
for ( EntityTableMapping tableMapping : entityPersister.getTableMappings() ) {
247+
if ( joinedTableReference.containsAffectedTableName( tableMapping.getTableName() ) ) {
248+
return tableMapping;
249+
}
250+
}
251+
throw new IllegalArgumentException( "Couldn't find subclass index for joined table reference " + joinedTableReference );
252+
}
253+
254+
private EntityPersister determineEntityPersister(ModelPartContainer modelPart) {
255+
if ( modelPart instanceof EntityPersister entityPersister ) {
256+
return entityPersister;
257+
}
258+
else if ( modelPart instanceof PluralAttributeMapping pluralAttributeMapping ) {
259+
return pluralAttributeMapping.getCollectionDescriptor().getElementPersister();
260+
}
261+
else if ( modelPart instanceof EntityAssociationMapping entityAssociationMapping ) {
262+
return entityAssociationMapping.getAssociatedEntityMappingType().getEntityPersister();
263+
}
264+
else {
265+
throw new IllegalArgumentException( "Expected table group with table joins to have an entity typed model part but got: " + modelPart );
228266
}
229-
return result;
230267
}
231268

232269
private String[] determineKeyColumnNames(ModelPart modelPart) {

0 commit comments

Comments
 (0)