Skip to content

Commit 5b49d5e

Browse files
committed
HHH-17164 - Proper, first-class soft-delete support
HHH-17311 - Reversed soft delete support https://hibernate.atlassian.net/browse/HHH-17164 https://hibernate.atlassian.net/browse/HHH-17311
1 parent ae3c88a commit 5b49d5e

File tree

4 files changed

+71
-54
lines changed

4 files changed

+71
-54
lines changed

documentation/src/main/asciidoc/userguide/chapters/domain/soft_delete.adoc

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,20 @@ Soft delete support is defined by 3 main parts -
2323

2424
1. The <<soft-delete-column,column>> which contains the indicator.
2525
2. A <<soft-delete-conversion,conversion>> from `Boolean` indicator value to the proper database type
26-
3. Whether to <<soft-delete-reverse,reverse>> the indicator values, tracking active/inactive instead
26+
3. A <<soft-delete-type,strategy>> for interpreting the stored indicator values.
2727

2828

2929
[[soft-delete-column]]
3030
==== Indicator column
3131

3232
The column where the indicator value is stored is defined using `@SoftDelete#columnName` attribute.
3333

34-
When using <<soft-delete-reverse,reversed>> mappings, the column name defaults to `active`; otherwise, it
35-
defaults to the name `deleted`.
34+
The default column name depends on the <<soft-delete-type,strategy>> being used -
35+
36+
ACTIVE::
37+
The default column name is `active`.
38+
DELETED::
39+
The default column name is `deleted`.
3640

3741
See <<soft-delete-basic-example>> for an example of customizing the column name.
3842

@@ -42,11 +46,11 @@ Depending on the conversion type, an appropriate check constraint may be applied
4246
[[soft-delete-conversion]]
4347
==== Indicator conversion
4448

45-
The conversion is defined using a JPA <<basic-jpa-convert,AttributeConverter>>. The "domain type" is always
46-
`boolean`. The "relational type" can be any type, as defined by the converter; generally `BOOLEAN`, `BIT`, `INTEGER` or `CHAR`.
49+
The conversion is defined using a Jakarta Persistence <<basic-jpa-convert,AttributeConverter>>. The domain-type is always
50+
`boolean`. The relational-type can be any type, as defined by the converter; generally `BOOLEAN`, `BIT`, `INTEGER` or `CHAR`.
4751

4852
An explicit conversion can be specified using `@SoftDelete#converter`. See <<soft-delete-basic-example>>
49-
for an example of specifying an explicit conversion. Explicit conversions can specify a custom converter or leverage the 3
53+
for an example of specifying an explicit conversion. Explicit conversions can specify a custom converter or leverage
5054
Hibernate-provided converters for the 3 most common cases -
5155

5256
`NumericBooleanConverter`:: Defines conversion using `0` for `false` and `1` for `true`
@@ -60,6 +64,8 @@ boolean (and bit):: the underlying type is boolean / bit and no conversion is ap
6064
numeric:: the underlying type is integer and values are converted according to `NumericBooleanConverter`
6165
character:: the underlying type is char and values are converted according to `TrueFalseConverter`
6266

67+
IMPORTANT: The converter should simply convert the `true` and `false`, irrespective of the <<soft-delete-type,strategy>> used. Hibernate will handle applying the strategy.
68+
6369

6470
[[soft-delete-entity]]
6571
==== Entity soft delete
@@ -133,35 +139,17 @@ The `@SoftDelete` annotation may also be placed at the package level, in which c
133139
entities and collections defined within the package.
134140

135141

136-
[[soft-delete-reverse]]
137-
==== Reversed soft delete
142+
[[soft-delete-type]]
143+
==== Strategy - SoftDeleteType
138144

139-
A common requirement in applications using soft delete is to track rows which are active as opposed to removed,
140-
reversing the boolean value. For example:
141-
142-
[[soft-delete-reverse-example]]
143-
.Reversed soft-delete
144-
====
145-
[source,java]
146-
----
147-
include::{testing-dir}/converter/reversed/TheEntity.java[tag=example-soft-delete-reverse, indent=0]
148-
----
149-
====
145+
Given truth values, there are 2 valid ways to interpret the values stored in the database. This
146+
interpretation is defined by the SoftDeleteType enumeration and can be configured per-usage using
147+
`@SoftDelete(..., strategy=ACTIVE)` or `@SoftDelete(..., strategy=DELETED)` -
150148

151-
When an instance of `TheEntity` is persisted, the value `'Y'` will be inserted into the
152-
`active` column. When an instance of `TheEntity` is removed, the column's value is updated to `'N'`.
153-
154-
This example explicitly specifies the built-in `YesNoConverter`, but reversal works with any conversion
155-
even implicit conversions -
156-
157-
[[soft-delete-reverse-example-2]]
158-
.Reversed soft-delete with implicit conversion
159-
====
160-
[source,java]
161-
----
162-
include::{testing-dir}/converter/reversed/TheEntity2.java[tag=example-soft-delete-reverse, indent=0]
163-
----
164-
====
149+
ACTIVE::
150+
Tracks rows which are active. A `true` value in the database indicates that the row is active
151+
(non-deleted); a `false` value indicates inactive (deleted).
152+
DELETED::
153+
Tracks rows which are deleted. A `true` value in the database indicates that the row is deleted;
154+
a `false` value indicates that the row is non-deleted.
165155

166-
The important thing to remember is that the stored values are reversed from the "normal" soft delete state.
167-
`active == true` is the same as `deleted == false` - both describe the same state.

hibernate-core/src/main/java/org/hibernate/annotations/SoftDelete.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@
6262
/**
6363
* (Optional) The name of the column.
6464
* <p/>
65-
* Default depends on {@linkplain #trackActive()} - {@code deleted} if {@code false} and
66-
* {@code active} if {@code true}.
65+
* Default depends on the {@linkplain #strategy() strategy} being used.
6766
*
6867
* @see SoftDeleteType#getDefaultColumnName()
6968
*/

migration-guide.adoc

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,14 @@ earlier versions, see any other pertinent migration guides as well.
1919
[[soft-delete]]
2020
== Soft Delete
2121

22-
6.4 adds support for soft deletes against an entity's primary table and collection tables, using the
23-
new `@SoftDelete` annotation.
24-
25-
[source,java]
26-
----
27-
@Entity
28-
@SoftDelete
29-
class Account {
30-
...
31-
}
32-
----
33-
22+
6.4 adds support for soft deletes, using the new `@SoftDelete` annotation.
3423
See the link:{userGuideBase}#soft-delete[User Guide] for details.
3524

25+
In previous versions, support for soft-deletes was somewhat implementable using
26+
a combination of any or all of event-listeners, filters, `@Where`, etc.
27+
Applications using such implementations are encouraged to switch.
28+
29+
3630
[[custom-tenant-identifier-type]]
3731
== Custom tenant identifier type
3832

release/src/release/announcement-template.adoc

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,56 @@
1-
:family: 6.3
2-
:version: 6.3.0.Final
3-
41
= Hibernate {version}
52
Steve Ebersole
63
:awestruct-tags: ["Hibernate ORM", "Releases"]
74
:awestruct-layout: blog-post
5+
6+
:version: 6.4.0.CR1
7+
:family: 6.4
8+
89
:docs-url: https://docs.jboss.org/hibernate/orm/{family}
910
:javadocs-url: {docs-url}/javadocs
1011
:migration-guide-url: {docs-url}/migration-guide/migration-guide.html
1112
:intro-guide-url: {docs-url}/introduction/html_single/Hibernate_Introduction.html
1213
:user-guide-url: {docs-url}/userguide/html_single/Hibernate_User_Guide.html
1314

14-
// Text ...
15+
6.4 adds some cool new features, in addition to many improvements and fixes.
16+
17+
[[soft-delete]]
18+
== Soft Delete
19+
20+
21+
6.4 adds support for soft deletes using the new `@SoftDelete` annotation.
22+
23+
[source,java]
24+
----
25+
@Entity
26+
@SoftDelete
27+
class Account {
28+
...
29+
}
30+
----
31+
32+
Dealing with values as deleted/non-deleted versus active/inactive (reversed) is simple using an annotation attribute:
33+
34+
This has the ability to easily handle active v. deleted tracking using a simple annotation attribute:
35+
36+
[source,java]
37+
----
38+
@Entity
39+
@SoftDelete(strategy=ACTIVE)
40+
class Account {
41+
...
42+
}
43+
----
44+
45+
It even supports pluggable converters for storing the indicator value into the database.strategy
46+
47+
See the link:{userGuideBase}#soft-delete[User Guide] for details.
48+
49+
50+
1551

1652

17-
== Conclusion
53+
== Finally,
1854

1955
For additional details, see:
2056

0 commit comments

Comments
 (0)