Skip to content

Commit e6451ac

Browse files
committed
HHH-17325 - @softdelete with timestamp
1 parent dda496f commit e6451ac

File tree

16 files changed

+318
-398
lines changed

16 files changed

+318
-398
lines changed

hibernate-core/src/main/java/org/hibernate/boot/model/internal/SoftDeleteHelper.java

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,13 @@
1616
import org.hibernate.mapping.SoftDeletable;
1717
import org.hibernate.mapping.Table;
1818
import org.hibernate.metamodel.mapping.SoftDeletableModelPart;
19-
import org.hibernate.metamodel.mapping.SoftDeleteMapping;
2019
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
2120
import org.hibernate.metamodel.mapping.internal.SoftDeleteMappingImpl;
22-
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
23-
import org.hibernate.sql.ast.tree.expression.ColumnReference;
24-
import org.hibernate.sql.ast.tree.expression.Expression;
25-
import org.hibernate.sql.ast.tree.expression.JdbcLiteral;
26-
import org.hibernate.sql.ast.tree.from.TableReference;
27-
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
28-
import org.hibernate.sql.ast.tree.predicate.Predicate;
29-
import org.hibernate.sql.ast.tree.update.Assignment;
3021

3122
import java.time.Instant;
3223

3324
import static org.hibernate.internal.util.StringHelper.coalesce;
3425
import static org.hibernate.internal.util.StringHelper.isBlank;
35-
import static org.hibernate.query.sqm.ComparisonOperator.EQUAL;
3626

3727
/**
3828
* Helper for dealing with {@link org.hibernate.annotations.SoftDelete}
@@ -95,6 +85,9 @@ private static Column createSoftDeleteIndicatorColumn(
9585
MetadataBuildingContext context) {
9686
final Column softDeleteColumn = new Column();
9787

88+
softDeleteColumn.setValue( softDeleteIndicatorValue );
89+
softDeleteIndicatorValue.addColumn( softDeleteColumn );
90+
9891
applyColumnName( softDeleteColumn, softDeleteConfig, context );
9992

10093
softDeleteColumn.setLength( 1 );
@@ -108,9 +101,6 @@ private static Column createSoftDeleteIndicatorColumn(
108101
softDeleteColumn.setComment( softDeleteConfig.comment() );
109102
}
110103

111-
softDeleteColumn.setValue( softDeleteIndicatorValue );
112-
softDeleteIndicatorValue.addColumn( softDeleteColumn );
113-
114104
return softDeleteColumn;
115105
}
116106

@@ -120,6 +110,7 @@ private static void applyColumnName(
120110
MetadataBuildingContext context) {
121111
final Database database = context.getMetadataCollector().getDatabase();
122112
final PhysicalNamingStrategy namingStrategy = context.getBuildingOptions().getPhysicalNamingStrategy();
113+
// NOTE : the argument order is strange here - the fallback value comes first
123114
final String logicalColumnName = coalesce(
124115
softDeleteConfig.strategy().getDefaultColumnName(),
125116
softDeleteConfig.columnName()
@@ -142,56 +133,4 @@ public static SoftDeleteMappingImpl resolveSoftDeleteMapping(
142133
return new SoftDeleteMappingImpl( softDeletableModelPart, bootMapping, tableName, creationProcess );
143134
}
144135

145-
/**
146-
* Create a SQL AST Predicate for restricting matches to non-deleted rows
147-
*
148-
* @param tableReference The table reference for the table containing the soft-delete column
149-
* @param softDeleteMapping The soft-delete mapping
150-
*/
151-
public static Predicate createNonSoftDeletedRestriction(
152-
TableReference tableReference,
153-
SoftDeleteMapping softDeleteMapping) {
154-
final ColumnReference softDeleteColumn = new ColumnReference( tableReference, softDeleteMapping );
155-
final JdbcLiteral<?> notDeletedLiteral = new JdbcLiteral<>(
156-
softDeleteMapping.getNonDeletedLiteralValue(),
157-
softDeleteMapping.getJdbcMapping()
158-
);
159-
return new ComparisonPredicate( softDeleteColumn, EQUAL, notDeletedLiteral );
160-
}
161-
162-
/**
163-
* Create a SQL AST Predicate for restricting matches to non-deleted rows
164-
*
165-
* @param tableReference The table reference for the table containing the soft-delete column
166-
* @param softDeleteMapping The soft-delete mapping
167-
*/
168-
public static Predicate createNonSoftDeletedRestriction(
169-
TableReference tableReference,
170-
SoftDeleteMapping softDeleteMapping,
171-
SqlExpressionResolver expressionResolver) {
172-
final Expression softDeleteColumn = expressionResolver.resolveSqlExpression( tableReference, softDeleteMapping );
173-
final JdbcLiteral<?> notDeletedLiteral = new JdbcLiteral<>(
174-
softDeleteMapping.getNonDeletedLiteralValue(),
175-
softDeleteMapping.getJdbcMapping()
176-
);
177-
return new ComparisonPredicate( softDeleteColumn, EQUAL, notDeletedLiteral );
178-
}
179-
180-
/**
181-
* Create a SQL AST Assignment for setting the soft-delete column to its
182-
* deleted indicate value
183-
*
184-
* @param tableReference The table reference for the table containing the soft-delete column
185-
* @param softDeleteMapping The soft-delete mapping
186-
*/
187-
public static Assignment createSoftDeleteAssignment(
188-
TableReference tableReference,
189-
SoftDeleteMapping softDeleteMapping) {
190-
final ColumnReference softDeleteColumn = new ColumnReference( tableReference, softDeleteMapping );
191-
final JdbcLiteral<?> softDeleteIndicator = new JdbcLiteral<>(
192-
softDeleteMapping.getDeletedLiteralValue(),
193-
softDeleteMapping.getJdbcMapping()
194-
);
195-
return new Assignment( softDeleteColumn, softDeleteIndicator );
196-
}
197136
}

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/SoftDeleteMapping.java

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
package org.hibernate.metamodel.mapping;
66

77
import org.hibernate.annotations.SoftDeleteType;
8+
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
9+
import org.hibernate.sql.ast.tree.expression.ColumnReference;
10+
import org.hibernate.sql.ast.tree.from.TableReference;
11+
import org.hibernate.sql.ast.tree.predicate.Predicate;
12+
import org.hibernate.sql.ast.tree.update.Assignment;
13+
import org.hibernate.sql.model.ast.ColumnValueBinding;
14+
import org.hibernate.sql.model.ast.builder.ColumnValuesTableMutationBuilder;
15+
import org.hibernate.sql.model.ast.builder.RestrictedTableMutationBuilder;
816

917
/**
1018
*
@@ -34,26 +42,47 @@ public interface SoftDeleteMapping extends SelectableMapping, VirtualModelPart,
3442
String getTableName();
3543

3644
/**
37-
* The SQL literal value which indicates a deleted row
45+
* Create a SQL AST Assignment for setting the soft-delete column to its indicated "deleted" value
46+
*
47+
* @param tableReference Reference for the table containing the soft-delete column
3848
*/
39-
Object getDeletedLiteralValue();
49+
Assignment createSoftDeleteAssignment(TableReference tableReference);
4050

4151
/**
42-
* The String representation of the SQL literal value which indicates a deleted row
52+
* Create a SQL AST Predicate for restricting matches to non-deleted rows
53+
*
54+
* @param tableReference Reference for the table containing the soft-delete column
4355
*/
44-
String getDeletedLiteralText();
56+
Predicate createNonDeletedRestriction(TableReference tableReference);
4557

4658
/**
47-
* The SQL literal value which indicates a non-deleted row
59+
* Create a SQL AST Predicate for restricting matches to non-deleted rows
4860
*
49-
* @apiNote The inverse of {@linkplain #getDeletedLiteralValue()}
61+
* @param tableReference Reference for the table containing the soft-delete column
62+
* @param expressionResolver Resolver for SQL AST Expressions
5063
*/
51-
Object getNonDeletedLiteralValue();
64+
Predicate createNonDeletedRestriction(TableReference tableReference, SqlExpressionResolver expressionResolver);
5265

5366
/**
54-
* The String representation of the SQL literal value which indicates a non-deleted row
67+
* Create a ColumnValueBinding for non-deleted indicator.
68+
*
69+
* @param softDeleteColumnReference Reference to the soft-delete column
70+
*
71+
* @apiNote Generally used as a restriction in a SQL AST
5572
*/
56-
String getNonDeletedLiteralText();
73+
ColumnValueBinding createNonDeletedValueBinding(ColumnReference softDeleteColumnReference);
74+
75+
/**
76+
* Create a ColumnValueBinding for deleted indicator.
77+
*
78+
* @param softDeleteColumnReference Reference to the soft-delete column
79+
*
80+
* @apiNote Generally used as an assignment in a SQL AST
81+
*/
82+
ColumnValueBinding createDeletedValueBinding(ColumnReference softDeleteColumnReference);
83+
84+
void applyNonDeletedRestriction(RestrictedTableMutationBuilder<?, ?> tableMutationBuilder);
85+
void applyDeletedAssignment(ColumnValuesTableMutationBuilder tableMutationBuilder);
5786

5887

5988
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -69,11 +98,6 @@ default String getSelectableName() {
6998
return getColumnName();
7099
}
71100

72-
@Override
73-
default String getWriteExpression() {
74-
return getNonDeletedLiteralText();
75-
}
76-
77101
@Override
78102
default String getContainingTableExpression() {
79103
return getTableName();

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/PluralAttributeMappingImpl.java

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package org.hibernate.metamodel.mapping.internal;
66

77
import org.checkerframework.checker.nullness.qual.Nullable;
8-
import org.hibernate.boot.model.internal.SoftDeleteHelper;
98
import org.hibernate.cache.MutableCacheKeyBuilder;
109
import org.hibernate.engine.FetchStyle;
1110
import org.hibernate.engine.FetchTiming;
@@ -73,7 +72,6 @@
7372
import java.util.function.Consumer;
7473
import java.util.function.Supplier;
7574

76-
import static org.hibernate.boot.model.internal.SoftDeleteHelper.createNonSoftDeletedRestriction;
7775
import static org.hibernate.boot.model.internal.SoftDeleteHelper.resolveSoftDeleteMapping;
7876

7977
/**
@@ -414,21 +412,18 @@ public void applySoftDeleteRestrictions(TableGroup tableGroup, PredicateConsumer
414412
final EntityMappingType associatedEntityDescriptor = elementDescriptor.getAssociatedEntityMappingType();
415413
final SoftDeleteMapping softDeleteMapping = associatedEntityDescriptor.getSoftDeleteMapping();
416414
if ( softDeleteMapping != null ) {
417-
final Predicate softDeleteRestriction = SoftDeleteHelper.createNonSoftDeletedRestriction(
418-
tableGroup.resolveTableReference( associatedEntityDescriptor.getSoftDeleteTableDetails().getTableName() ),
419-
softDeleteMapping
420-
);
415+
final String primaryTableName = associatedEntityDescriptor.getSoftDeleteTableDetails().getTableName();
416+
final TableReference primaryTableReference = tableGroup.resolveTableReference( primaryTableName );
417+
final Predicate softDeleteRestriction = softDeleteMapping.createNonDeletedRestriction( primaryTableReference );
421418
predicateConsumer.applyPredicate( softDeleteRestriction );
422419
}
423420
}
424421

425422
// apply the collection's soft-delete mapping, if one
426423
final SoftDeleteMapping softDeleteMapping = getSoftDeleteMapping();
427424
if ( softDeleteMapping != null ) {
428-
final Predicate softDeleteRestriction = SoftDeleteHelper.createNonSoftDeletedRestriction(
429-
tableGroup.resolveTableReference( getSoftDeleteTableDetails().getTableName() ),
430-
softDeleteMapping
431-
);
425+
final TableReference primaryTableReference = tableGroup.resolveTableReference( getSoftDeleteTableDetails().getTableName() );
426+
final Predicate softDeleteRestriction = softDeleteMapping.createNonDeletedRestriction( primaryTableReference );
432427
predicateConsumer.applyPredicate( softDeleteRestriction );
433428
}
434429
}
@@ -791,9 +786,8 @@ private void applySoftDeleteRestriction(
791786
final SoftDeleteMapping softDeleteMapping = entityMappingType.getSoftDeleteMapping();
792787
if ( softDeleteMapping != null ) {
793788
final TableDetails softDeleteTable = entityMappingType.getSoftDeleteTableDetails();
794-
predicateConsumer.accept( createNonSoftDeletedRestriction(
789+
predicateConsumer.accept( softDeleteMapping.createNonDeletedRestriction(
795790
tableGroup.resolveTableReference( softDeleteTable.getTableName() ),
796-
softDeleteMapping,
797791
creationState.getSqlExpressionResolver()
798792
) );
799793
}
@@ -802,9 +796,8 @@ private void applySoftDeleteRestriction(
802796
final SoftDeleteMapping softDeleteMapping = getSoftDeleteMapping();
803797
if ( softDeleteMapping != null ) {
804798
final TableDetails softDeleteTable = getSoftDeleteTableDetails();
805-
predicateConsumer.accept( createNonSoftDeletedRestriction(
799+
predicateConsumer.accept( softDeleteMapping.createNonDeletedRestriction(
806800
tableGroup.resolveTableReference( softDeleteTable.getTableName() ),
807-
softDeleteMapping,
808801
creationState.getSqlExpressionResolver()
809802
) );
810803
}

0 commit comments

Comments
 (0)