Interface EntityEditor.DetailEditors<R extends EntityEditor<R>>
- Type Parameters:
R-EntityEditortype
- Enclosing interface:
EntityEditor<R extends EntityEditor<R>>
Manages detail editors for one-to-one entity composition within an EntityEditor.
A detail editor represents a detail entity that is edited alongside the master and persisted
within the same transaction. The relationship between master and detail is described by an
EditorLink, which can be either foreign-key based
or condition-based.
Foreign-key based links
When the link is a ForeignKeyEditorLink, the foreign key to the master is
declared framework-managed via three coordinated configurations on the detail editor:
- The foreign key value is not reset by defaults — its
EntityEditor.EditorValue.persist()is set to false, so it survivesEntityEditor.EditorValues.defaults(). - The detail editor's validator is wrapped so a null foreign key is silently accepted during validation.
This applies both to the reactive
EntityEditor.valid()state (for UI binding) and to the validation gate inEntityEditor.EditorTasks.insert(java.util.function.Consumer)(which must throw synchronously, before the framework has populated the foreign key). The wrapped validator is locked to prevent replacement. - The framework sets the foreign key on the detail entity during persistence, linking it to the
freshly-inserted master (via the link's
beforeInsertaction).
Together, these make the foreign key invisible to user-supplied logic — it is filled in by the framework at persistence time and ignored everywhere else.
Condition-based links
When the link has no foreign key, none of the framework-managed declarations apply. The user supplies
the load condition (how to load the detail row given the master) and
the beforeInsert action (how to prepare the detail for insertion). It is
the user's responsibility to ensure these two stay consistent: any row created via beforeInsert
must match the load condition, otherwise the row will persist but never load back on subsequent master
selection.
Persistence flow
The detail entity is loaded from the database when the master entity changes, and the master editor's
EntityEditor.Modified state aggregates the detail editor's state.
During master persistence, detail editors participate within the same transaction
(see EntityConnection.transaction(is.codion.framework.db.EntityConnection, is.codion.framework.db.EntityConnection.Transactional) — a transaction call on a connection that
already has an open transaction joins the outer one rather than starting a new one):
- Insert: A present detail entity is inserted, with the link's
beforeInsertapplied with the freshly-inserted master. - Update: Depending on the detail's presence and existence, the detail is inserted, updated, or deleted.
- Delete: An existing detail entity is deleted before the master.
Presence is determined by the detail editor's EntityEditor.present() state, configured
at registration time via EditorLink.Builder.present(Predicate). A detail that is present but
does not yet exist triggers an insert. A detail that exists but is no longer present triggers a
delete. A detail that exists, is present, and is modified triggers an update.
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionvoidadd(EditorLink link) Registers a detail editor described by the given link.caption(ForeignKey foreignKey) get(ForeignKey foreignKey) Looks up a previously registered detail editor by foreign key.
-
Method Details
-
add
Registers a detail editor described by the given link.
For
foreign-key basedlinks the framework-managed FK declarations described in the class javadoc are applied to the detail editor. For condition-based links no automatic FK management is applied — the user-suppliedload conditionandbeforeInsertdrive the relationship.- Parameters:
link- the detail editor link- Throws:
IllegalArgumentException- if a detail editor with the same name is already registered, or, for an FK-based link, if the foreign key's referenced or owning entity types don't match the master and detail editors respectively- See Also:
-
get
Looks up a previously registered detail editor by foreign key.
Returns the registered
ForeignKeyEditorLink-based detail editor whose foreign key matches, regardless of any explicit name override. For multi-slot configurations where several detail editors share the same foreign key, this method throws — useget(String)with an explicit name instead.- Parameters:
foreignKey- the foreign key- Returns:
- the detail editor previously registered for the given foreign key
- Throws:
IllegalStateException- if no detail editor is registered for the foreign key, or if multiple detail editors are registered for it
-
get
- Parameters:
name- the link name- Returns:
- the detail editor previously registered with the given name
- Throws:
IllegalStateException- if no detail editor is registered under the given name
-
caption
- Parameters:
name- the link name- Returns:
- the caption of the link registered with the given name
- Throws:
IllegalStateException- if no detail editor is registered under the given name, or if multiple detail editors share the name (usecaption(ForeignKey))
-
caption
- Parameters:
foreignKey- the foreign key- Returns:
- the caption of the link registered for the given foreign key
- Throws:
IllegalStateException- if no detail editor is registered for the foreign key, or if multiple detail editors are registered for it (usecaption(String))
-