Join Table
To enable logical deletion for the middle table, the property needs to be specified for the org.babyfish.jimmer.sql.JoinTable
annotation to indicate whether the data is normal or has been deleted.
-
Once a logical deletion attribute is configured for the middle table, when any entity on either end is logically deleted, all related middle table records will be logically deleted.
-
All JOIN operations for the current association will be automatically added with the condition
and logical deletion flag <> already deleted
to give the illusion that some associations have been deleted.
Usage
The logical deletion flag attribute can be one of the following types:
- boolean: must be non-null
- int: must be non-null
- enum: must be non-null
- long/Long: can be null or non-null
- UUID: must be non-null
- Date: must be nullable
Type | Code | Deleted State | Initialized State |
---|---|---|---|
boolean |
| true | false |
| false | true | |
int |
| 1 | 0 |
Enum |
| DELETED | INITIALIZED |
✩ long |
| Current milliseconds | 0L |
✩ Nullable Long |
| Current milliseconds | null |
✩ UUID |
| Random UUID | UUID with all bytes as 0 |
✩ Nullable UUID |
| Random UUID | null |
Nullable LocalDateTime | ✩
| Current Time | null |
| null | Current Time |
Where
-
✩ in the first or second column indicates that the current configuration method supports multi-version data to be discussed in the next section.
infoSupporting logical deletion without considering multi-version data issues is less mature. Therefore, it is recommended to use the logical deletion configuration that supports multi-version data.
-
Current milliseconds
, the default behavior isSystem.currentMillis()
, which is the behavior of the defaultorg.babyfish.jimmer.sql.meta.LogicalDeletedLongGenerator
.If this behavior is unsatisfactory, a custom class can be implemented that implements the
LogicalDeletedValueGenerator<Long>
interface, and configured with:-
@JoinTable.LogicalDeletedFilter(generatedType = YourGenerator.class)
-
@JoinTable.LogicalDeletedFilter(generatedRef = YourGenerator.class)
, wheregeneratorRef
indicates the name of the object in the IOC container management framework
-
-
Random UUID
, the default behavior isUUID.randomUUID()
, which is the behavior of the defaultorg.babyfish.jimmer.sql.meta.LogicalDeletedUUIDGenerator
.If this behavior is unsatisfactory, a custom class can be implemented that implements the
LogicalDeletedValueGenerator<UUID>
interface, and configured with:-
@JoinTable.LogicalDeletedFilter(generatedType = YourGenerator.class)
-
@JoinTable.LogicalDeletedFilter(generatedRef = YourGenerator.class)
, wheregeneratorRef
indicates the name of the object in the IOC container management framework
-
Multi-Version Data
Logical deletion does not actually delete data, it only hides it. This means that data appears in multiple versions.
Take the configuration that supports multi-version data as an example:
- Java
- Kotlin
@ManyToMany
@JoinTable(
name = "BOOK_AUTHOR_MAPPING",
joinColumnName = "BOOK_ID",
inverseJoinColumnName = "AUTHOR_ID",
logicalDeletedFilter =
@JoinTable.LogicalDeletedFilter(
columnName = "DELETED_MILLIS",
type = long.class
)
)
List<Author> authors();
@ManyToMany
@JoinTable(
name = "BOOK_AUTHOR_MAPPING",
joinColumnName = "BOOK_ID",
inverseJoinColumnName = "AUTHOR_ID",|
logicalDeletedFilter =
@JoinTable.LogicalDeletedFilter(
columnName = "DELETED_MILLIS",
type = long.class
)
)
val authors: List<Author>
For example, the BOOK_AUTHOR_MAPPING
table has three columns, all as part of the primary key
alter table BOOK_AUTHOR_MAPPING
add pk_BOOK_AUTHOR_MAPPING
primary key(
BOOK_ID,
AUTHOR_ID,
DELETED_MILLIS
);
If the table input is as follows:
BOOK_ID | AUTHOR_ID | DELETED_MILLIS |
---|---|---|
97 | 23 | 0 |
97 | 23 | 1708796420956 |
97 | 23 | 1708234681901 |
249 | 11 | 0 |
249 | 11 | 1708722582793 |
249 | 11 | 1708664484823 |
There are 4 associated data records hidden, leaving only two valid data records:
BOOK_ID | AUTHOR_ID | DELETED_MILLIS |
---|---|---|
97 | 23 | 0 |
249 | 11 | 0 |