Mutations
Saving Derived Objects
Save the actual derived entity object. Jimmer derives the discriminator from its type and writes every physical stage required by the mapping strategy.
- Java
- Kotlin
Organization organization = Immutables.createOrganization(draft -> {
draft.setId(100L);
draft.setName("Acme");
draft.setTaxCode("ACME-001");
});
sqlClient.getEntities().save(organization);
sqlClient.save(
Organization {
id = 100L
name = "Acme"
taxCode = "ACME-001"
}
)
For SINGLE_TABLE, this is one row containing the root and derived properties.
For JOINED, Jimmer coordinates the root and derived table statements as one
save operation. Batch saves are grouped by actual type and physical stage.
The same behavior applies when inherited entities appear inside a graph save. Optimistic locking, transaction triggers, associations, logical deletion, and assignment expressions continue to work at the appropriate stage.
Abstract Types
An abstract inheritance type cannot be inserted or upserted because it has no
discriminator value of its own. It can be used with UPDATE_ONLY to update
properties shared by all matching concrete branches:
sqlClient
.getEntities()
.saveCommand(clientWithOnlyIdAndName)
.setMode(SaveMode.UPDATE_ONLY)
.execute();
For this operation, type changes must be disabled and the type match mode must
be AUTO or POLYMORPHIC.
Type Match Mode
Save, update, and delete commands use the same TypeMatchMode values as root
queries:
AUTOmatches an instantiable type exactly and an abstract type polymorphically.EXACTmatches only the requested type.POLYMORPHICmatches the requested type and every instantiable subtype.
Mutation commands use AUTO by default.
For a save command:
command.setTypeMatchMode(TypeMatchMode.POLYMORPHIC);
For a Kotlin save DSL:
setTypeMatchMode(TypeMatchMode.POLYMORPHIC)
The mode can also be configured for associated entities with
setAssociatedTypeMatchModeAll, by entity type, or by association property.
Mutable update and delete statements expose setTypeMatchMode as well.
Changing the Entity Type
Changing an existing id from one inheritance branch to another is disabled by default. This prevents an object of the wrong runtime type from silently rewriting the discriminator and, for joined inheritance, moving data between derived tables.
Enable it only for commands where such a transition is part of the business operation:
- Java
- Kotlin
sqlClient
.getEntities()
.saveCommand(organization)
.setTypeChangeAllowed(true)
.execute();
sqlClient.save(organization) {
setTypeChangeAllowed()
}
It can be enabled globally with setDefaultTypeChangeAllowed, or separately for
associated entities with the setAssociatedTypeChangeAllowed* APIs.
typeChangeAllowed cannot be combined with polymorphic save matching. The
command must identify one exact source branch before it can safely perform a
type transition.
Delete Semantics for Joined Inheritance
Deleting a joined derived type removes its derived rows and the root row while respecting associations, triggers, and logical deletion. Deleting an abstract or polymorphically matched type routes each id through the applicable physical branch.
The mapping-level joinedTableDissociateAction controls whether Jimmer deletes
derived table rows explicitly (DELETE, the default) or relies on database
ON DELETE CASCADE (LAX). See Entity Mapping.