Skip to content

Commit eb845ec

Browse files
committed
Also handle join tables for RowLockStrategy.COLUMN
1 parent 12252c4 commit eb845ec

File tree

1 file changed

+53
-8
lines changed

1 file changed

+53
-8
lines changed

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

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,26 @@
1010
import org.hibernate.dialect.RowLockStrategy;
1111
import org.hibernate.internal.util.collections.CollectionHelper;
1212
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
13+
import org.hibernate.metamodel.mapping.EntityMappingType;
1314
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
1415
import org.hibernate.metamodel.mapping.ModelPart;
16+
import org.hibernate.metamodel.mapping.ModelPartContainer;
1517
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
18+
import org.hibernate.metamodel.mapping.TableDetails;
1619
import org.hibernate.metamodel.mapping.ValuedModelPart;
1720
import org.hibernate.metamodel.mapping.internal.BasicValuedCollectionPart;
1821
import org.hibernate.persister.entity.EntityPersister;
22+
import org.hibernate.persister.entity.mutation.EntityTableMapping;
1923
import org.hibernate.sql.ast.SqlAstJoinType;
2024
import org.hibernate.sql.ast.spi.LockingClauseStrategy;
2125
import org.hibernate.sql.ast.spi.SqlAppender;
26+
import org.hibernate.sql.ast.tree.from.NamedTableReference;
2227
import org.hibernate.sql.ast.tree.from.TableGroup;
2328
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
2429
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
30+
import org.hibernate.sql.model.TableMapping;
2531

2632
import java.util.ArrayList;
27-
import java.util.Collections;
2833
import java.util.HashSet;
2934
import java.util.LinkedHashSet;
3035
import java.util.List;
@@ -212,21 +217,61 @@ private void addTableAliases(TableGroup tableGroup, List<String> lockItems) {
212217
}
213218

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

232277
private String[] determineKeyColumnNames(ModelPart modelPart) {

0 commit comments

Comments
 (0)