Skip to content

Commit 5635a33

Browse files
committed
HHH-17105 Include custom sql restriction in join table mutations
1 parent 5d33ada commit 5635a33

File tree

9 files changed

+126
-23
lines changed

9 files changed

+126
-23
lines changed

hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1782,7 +1782,8 @@ public RestrictedTableMutation<JdbcMutationOperation> generateDeleteAllAst(Mutat
17821782
"one-shot delete for " + getRolePath(),
17831783
keyRestrictionBindings,
17841784
Collections.emptyList(),
1785-
parameterBinders
1785+
parameterBinders,
1786+
sqlWhereString
17861787
);
17871788
}
17881789

hibernate-core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,12 @@ private RestrictedTableMutation<JdbcMutationOperation> generateUpdateRowAst(Muta
458458
final PluralAttributeMapping attribute = getAttributeMapping();
459459
assert attribute != null;
460460

461-
final TableUpdateBuilderStandard<?> updateBuilder = new TableUpdateBuilderStandard<>( this, tableReference, getFactory() );
461+
final TableUpdateBuilderStandard<?> updateBuilder = new TableUpdateBuilderStandard<>(
462+
this,
463+
tableReference,
464+
getFactory(),
465+
sqlWhereString
466+
);
462467

463468
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
464469
// SET
@@ -667,7 +672,12 @@ private RestrictedTableMutation<JdbcMutationOperation> generateDeleteRowAst(Muta
667672
final ForeignKeyDescriptor fkDescriptor = pluralAttribute.getKeyDescriptor();
668673
assert fkDescriptor != null;
669674

670-
final TableDeleteBuilderStandard deleteBuilder = new TableDeleteBuilderStandard( this, tableReference, getFactory() );
675+
final TableDeleteBuilderStandard deleteBuilder = new TableDeleteBuilderStandard(
676+
this,
677+
tableReference,
678+
getFactory(),
679+
sqlWhereString
680+
);
671681

672682
if ( pluralAttribute.getIdentifierDescriptor() != null ) {
673683
deleteBuilder.addKeyRestrictionsLeniently( pluralAttribute.getIdentifierDescriptor() );

hibernate-core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,12 @@ private JdbcMutationOperation buildGeneratedDeleteRowOperation(MutatingTableRefe
564564
}
565565

566566
public RestrictedTableMutation<JdbcMutationOperation> generateDeleteRowAst(MutatingTableReference tableReference) {
567-
final TableUpdateBuilderStandard<MutationOperation> updateBuilder = new TableUpdateBuilderStandard<>( this, tableReference, getFactory() );
567+
final TableUpdateBuilderStandard<MutationOperation> updateBuilder = new TableUpdateBuilderStandard<>(
568+
this,
569+
tableReference,
570+
getFactory(),
571+
sqlWhereString
572+
);
568573

569574
// for each key column -
570575
// 1) set the value to null
@@ -654,9 +659,14 @@ private JdbcMutationOperation generateInsertRowOperation(MutatingTableReference
654659
}
655660

656661
private TableUpdate<JdbcMutationOperation> buildTableUpdate(MutatingTableReference tableReference) {
657-
final TableUpdateBuilderStandard<JdbcMutationOperation> updateBuilder = new TableUpdateBuilderStandard<>( this, tableReference, getFactory() );
658-
final PluralAttributeMapping attributeMapping = getAttributeMapping();
662+
final TableUpdateBuilderStandard<JdbcMutationOperation> updateBuilder = new TableUpdateBuilderStandard<>(
663+
this,
664+
tableReference,
665+
getFactory(),
666+
sqlWhereString
667+
);
659668

669+
final PluralAttributeMapping attributeMapping = getAttributeMapping();
660670
attributeMapping.getKeyDescriptor().getKeyPart().forEachSelectable( updateBuilder );
661671

662672
final CollectionPart indexDescriptor = attributeMapping.getIndexDescriptor();
@@ -757,7 +767,12 @@ private JdbcMutationOperation buildCustomSqlWriteIndexOperation(MutatingTableRef
757767
}
758768

759769
private JdbcMutationOperation buildGeneratedWriteIndexOperation(MutatingTableReference tableReference) {
760-
final TableUpdateBuilderStandard<JdbcMutationOperation> updateBuilder = new TableUpdateBuilderStandard<>( this, tableReference, getFactory() );
770+
final TableUpdateBuilderStandard<JdbcMutationOperation> updateBuilder = new TableUpdateBuilderStandard<>(
771+
this,
772+
tableReference,
773+
getFactory(),
774+
sqlWhereString
775+
);
761776

762777
final OneToManyCollectionPart elementDescriptor = (OneToManyCollectionPart) getAttributeMapping().getElementDescriptor();
763778
updateBuilder.addKeyRestrictionsLeniently( elementDescriptor.getAssociatedEntityMappingType().getIdentifierMapping() );

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleDeleteQueryPlan.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
import java.util.Map;
1111

1212
import org.hibernate.action.internal.BulkOperationCleanupAction;
13+
import org.hibernate.dialect.DmlTargetColumnQualifierSupport;
1314
import org.hibernate.engine.jdbc.spi.JdbcServices;
1415
import org.hibernate.engine.spi.SessionFactoryImplementor;
1516
import org.hibernate.engine.spi.SharedSessionContractImplementor;
17+
import org.hibernate.internal.util.MutableObject;
1618
import org.hibernate.metamodel.mapping.EntityMappingType;
1719
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
1820
import org.hibernate.metamodel.mapping.MappingModelExpressible;
@@ -35,7 +37,9 @@
3537
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
3638
import org.hibernate.sql.ast.tree.from.MutatingTableReferenceGroupWrapper;
3739
import org.hibernate.sql.ast.tree.from.NamedTableReference;
40+
import org.hibernate.sql.ast.tree.from.TableGroup;
3841
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
42+
import org.hibernate.sql.ast.tree.predicate.Predicate;
3943
import org.hibernate.sql.ast.tree.select.QuerySpec;
4044
import org.hibernate.sql.exec.spi.JdbcOperationQueryDelete;
4145
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
@@ -136,17 +140,29 @@ public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T
136140
SqmMutationStrategyHelper.cleanUpCollectionTables(
137141
entityDescriptor,
138142
(tableReference, attributeMapping) -> {
143+
final TableGroup collectionTableGroup = new MutatingTableReferenceGroupWrapper(
144+
new NavigablePath( attributeMapping.getRootPathName() ),
145+
attributeMapping,
146+
(NamedTableReference) tableReference
147+
);
148+
149+
final MutableObject<Predicate> additionalPredicate = new MutableObject<>();
150+
attributeMapping.applyBaseRestrictions(
151+
p -> additionalPredicate.set( Predicate.combinePredicates( additionalPredicate.get(), p ) ),
152+
collectionTableGroup,
153+
factory.getJdbcServices().getDialect().getDmlTargetColumnQualifierSupport() == DmlTargetColumnQualifierSupport.TABLE_ALIAS,
154+
executionContext.getSession().getLoadQueryInfluencers().getEnabledFilters(),
155+
null,
156+
null
157+
);
158+
139159
if ( missingRestriction ) {
140-
return null;
160+
return additionalPredicate.get();
141161
}
142162

143163
final ForeignKeyDescriptor fkDescriptor = attributeMapping.getKeyDescriptor();
144164
final Expression fkColumnExpression = MappingModelCreationHelper.buildColumnReferenceExpression(
145-
new MutatingTableReferenceGroupWrapper(
146-
new NavigablePath( attributeMapping.getRootPathName() ),
147-
attributeMapping,
148-
(NamedTableReference) tableReference
149-
),
165+
collectionTableGroup,
150166
fkDescriptor.getKeyPart(),
151167
null,
152168
factory
@@ -178,7 +194,10 @@ public <T> MappingModelExpressible<T> getResolvedMappingModelType(SqmParameter<T
178194
session
179195
) );
180196

181-
return new InSubQueryPredicate( fkColumnExpression, matchingIdSubQuery, false );
197+
return Predicate.combinePredicates(
198+
additionalPredicate.get(),
199+
new InSubQueryPredicate( fkColumnExpression, matchingIdSubQuery, false )
200+
);
182201
},
183202
( missingRestriction ? JdbcParameterBindings.NO_BINDINGS : jdbcParameterBindings ),
184203
executionContextAdapter

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8126,6 +8126,10 @@ public void visitStandardTableDelete(TableDeleteStandard tableDelete) {
81268126
}
81278127
} );
81288128
}
8129+
8130+
if ( tableDelete.getWhereFragment() != null ) {
8131+
sqlBuffer.append( " and (" ).append( tableDelete.getWhereFragment() ).append( ")" );
8132+
}
81298133
}
81308134
finally {
81318135
getCurrentClauseStack().pop();

hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/TableDeleteBuilderStandard.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,12 @@
66
*/
77
package org.hibernate.sql.model.ast.builder;
88

9-
import java.util.ArrayList;
10-
import java.util.List;
11-
129
import org.hibernate.HibernateException;
1310
import org.hibernate.engine.spi.SessionFactoryImplementor;
11+
import org.hibernate.internal.util.StringHelper;
1412
import org.hibernate.sql.model.MutationTarget;
1513
import org.hibernate.sql.model.MutationType;
1614
import org.hibernate.sql.model.TableMapping;
17-
import org.hibernate.sql.model.ast.ColumnValueParameter;
1815
import org.hibernate.sql.model.ast.MutatingTableReference;
1916
import org.hibernate.sql.model.ast.TableDelete;
2017
import org.hibernate.sql.model.internal.TableDeleteCustomSql;
@@ -34,21 +31,32 @@ public class TableDeleteBuilderStandard
3431

3532
private String sqlComment;
3633

34+
private final String whereFragment;
35+
3736
public TableDeleteBuilderStandard(
3837
MutationTarget<?> mutationTarget,
3938
TableMapping table,
4039
SessionFactoryImplementor sessionFactory) {
41-
this( mutationTarget, new MutatingTableReference( table ), sessionFactory );
40+
this( mutationTarget, new MutatingTableReference( table ), sessionFactory, null );
4241
}
4342

4443
public TableDeleteBuilderStandard(
4544
MutationTarget<?> mutationTarget,
4645
MutatingTableReference tableReference,
4746
SessionFactoryImplementor sessionFactory) {
47+
this( mutationTarget, tableReference, sessionFactory, null );
48+
}
49+
50+
public TableDeleteBuilderStandard(
51+
MutationTarget<?> mutationTarget,
52+
MutatingTableReference tableReference,
53+
SessionFactoryImplementor sessionFactory,
54+
String whereFragment) {
4855
super( MutationType.DELETE, mutationTarget, tableReference, sessionFactory );
4956

5057
this.isCustomSql = tableReference.getTableMapping().getDeleteDetails().getCustomSql() != null;
5158
this.sqlComment = "delete for " + mutationTarget.getRolePath();
59+
this.whereFragment = whereFragment;
5260
}
5361

5462
public String getSqlComment() {
@@ -98,7 +106,8 @@ public TableDelete buildMutation() {
98106
sqlComment,
99107
getKeyRestrictionBindings(),
100108
getOptimisticLockBindings(),
101-
getParameters()
109+
getParameters(),
110+
whereFragment
102111
);
103112
}
104113
}

hibernate-core/src/main/java/org/hibernate/sql/model/ast/builder/TableUpdateBuilderStandard.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88

99
import java.util.List;
1010

11+
import org.hibernate.HibernateException;
1112
import org.hibernate.engine.spi.SessionFactoryImplementor;
13+
import org.hibernate.internal.util.StringHelper;
1214
import org.hibernate.sql.model.MutationOperation;
1315
import org.hibernate.sql.model.MutationTarget;
1416
import org.hibernate.sql.model.TableMapping;
@@ -26,19 +28,30 @@
2628
* @author Steve Ebersole
2729
*/
2830
public class TableUpdateBuilderStandard<O extends MutationOperation> extends AbstractTableUpdateBuilder<O> {
31+
private final String whereFragment;
2932

3033
public TableUpdateBuilderStandard(
3134
MutationTarget<?> mutationTarget,
3235
TableMapping tableMapping,
3336
SessionFactoryImplementor sessionFactory) {
3437
super( mutationTarget, tableMapping, sessionFactory );
38+
this.whereFragment = null;
3539
}
3640

3741
public TableUpdateBuilderStandard(
3842
MutationTarget<?> mutationTarget,
3943
MutatingTableReference tableReference,
4044
SessionFactoryImplementor sessionFactory) {
45+
this( mutationTarget, tableReference, sessionFactory, null );
46+
}
47+
48+
public TableUpdateBuilderStandard(
49+
MutationTarget<?> mutationTarget,
50+
MutatingTableReference tableReference,
51+
SessionFactoryImplementor sessionFactory,
52+
String whereFragment) {
4153
super( mutationTarget, tableReference, sessionFactory );
54+
this.whereFragment = whereFragment;
4255
}
4356

4457
@SuppressWarnings("unchecked")
@@ -76,7 +89,9 @@ public RestrictedTableMutation<O> buildMutation() {
7689
getSqlComment(),
7790
valueBindings,
7891
getKeyRestrictionBindings(),
79-
getOptimisticLockBindings()
92+
getOptimisticLockBindings(),
93+
whereFragment,
94+
null
8095
);
8196
}
8297
}

hibernate-core/src/main/java/org/hibernate/sql/model/internal/TableDeleteStandard.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,32 @@
1919
* @author Steve Ebersole
2020
*/
2121
public class TableDeleteStandard extends AbstractTableDelete {
22+
private final String whereFragment;
23+
2224
public TableDeleteStandard(
2325
MutatingTableReference mutatingTable,
2426
MutationTarget<?> mutationTarget,
2527
String sqlComment,
2628
List<ColumnValueBinding> keyRestrictionBindings,
2729
List<ColumnValueBinding> optLockRestrictionBindings,
2830
List<ColumnValueParameter> parameters) {
31+
this( mutatingTable, mutationTarget, sqlComment, keyRestrictionBindings, optLockRestrictionBindings, parameters, null );
32+
}
33+
34+
public TableDeleteStandard(
35+
MutatingTableReference mutatingTable,
36+
MutationTarget<?> mutationTarget,
37+
String sqlComment,
38+
List<ColumnValueBinding> keyRestrictionBindings,
39+
List<ColumnValueBinding> optLockRestrictionBindings,
40+
List<ColumnValueParameter> parameters,
41+
String whereFragment) {
2942
super( mutatingTable, mutationTarget, sqlComment, keyRestrictionBindings, optLockRestrictionBindings, parameters );
43+
this.whereFragment = whereFragment;
44+
}
45+
46+
public String getWhereFragment() {
47+
return whereFragment;
3048
}
3149

3250
@Override

hibernate-core/src/main/java/org/hibernate/sql/model/internal/TableUpdateStandard.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,21 @@ public TableUpdateStandard(
3232
List<ColumnValueBinding> valueBindings,
3333
List<ColumnValueBinding> keyRestrictionBindings,
3434
List<ColumnValueBinding> optLockRestrictionBindings) {
35+
this( mutatingTable, mutationTarget, sqlComment, valueBindings, keyRestrictionBindings, optLockRestrictionBindings, null, null );
36+
}
37+
38+
public TableUpdateStandard(
39+
MutatingTableReference mutatingTable,
40+
MutationTarget<?> mutationTarget,
41+
String sqlComment,
42+
List<ColumnValueBinding> valueBindings,
43+
List<ColumnValueBinding> keyRestrictionBindings,
44+
List<ColumnValueBinding> optLockRestrictionBindings,
45+
String whereFragment,
46+
Expectation expectation) {
3547
super( mutatingTable, mutationTarget, sqlComment, valueBindings, keyRestrictionBindings, optLockRestrictionBindings );
36-
this.whereFragment = null;
37-
this.expectation = null;
48+
this.whereFragment = whereFragment;
49+
this.expectation = expectation;
3850
}
3951

4052
public TableUpdateStandard(

0 commit comments

Comments
 (0)