From 1dcabfad2c966e6b490a08265fc6e4654a183ee5 Mon Sep 17 00:00:00 2001 From: Robin de Silva Jayasinghe Date: Mon, 20 Apr 2026 12:25:18 +0200 Subject: [PATCH 1/6] docs(java): update fiori-drafts table for draftNew / post-active semantics Reflect the new POST behavior introduced when an entity has a `@Common.DraftRoot.NewAction` (draftNew action): a plain POST now creates an active entity instead of a draft, while `POST /draftNew` creates the draft. Also document that `cds.drafts.post-active` is auto-detected from the annotation presence rather than requiring explicit configuration. --- java/fiori-drafts.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/java/fiori-drafts.md b/java/fiori-drafts.md index 973dfd314..7bd1ef8f9 100644 --- a/java/fiori-drafts.md +++ b/java/fiori-drafts.md @@ -70,16 +70,19 @@ When users edit a draft-enabled entity in the frontend, the following requests a Draft-enabled entities have an extra key `IsActiveEntity` by which you can access either the active entity or the draft (inactive entity). ::: -| HTTP / OData request | Event constant name | Default implementation | -| -------------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| POST | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | -| PATCH with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_PATCH` | Updates an existing draft | -| DELETE with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_CANCEL` | Deletes an existing draft | -| DELETE with key `IsActiveEntity=true` | `CqnService.EVENT_DELETE` | Deletes an active entity *and* the corresponding draft | -| POST with action `draftPrepare` | `DraftService.EVENT_DRAFT_PREPARE` | Empty implementation | -| POST with action `draftEdit` | `DraftService.EVENT_DRAFT_EDIT` | Creates a new draft from an active entity. Internally triggers `DRAFT_CREATE`. | -| POST with action `draftActivate` | `DraftService.EVENT_DRAFT_SAVE` | Activates a draft and updates the active entity. Triggers an `CREATE` or `UPDATE` event on the affected entity. | -| n/a | `DraftService.EVENT_DRAFT_CREATE` | Stores a new draft in the database. | +| HTTP / OData request | Event constant name | Default implementation | +| ---------------------------------------------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| POST with `IsActiveEntity=false` in payload | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | +| POST (no `IsActiveEntity`) on entity *without* a `draftNew` action | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | +| POST (no `IsActiveEntity`) on entity *with* a `draftNew` action | `CqnService.EVENT_CREATE` | Creates a new active entity. | +| POST with action `draftNew` | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | +| PATCH with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_PATCH` | Updates an existing draft | +| DELETE with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_CANCEL` | Deletes an existing draft | +| DELETE with key `IsActiveEntity=true` | `CqnService.EVENT_DELETE` | Deletes an active entity *and* the corresponding draft | +| POST with action `draftPrepare` | `DraftService.EVENT_DRAFT_PREPARE` | Empty implementation | +| POST with action `draftEdit` | `DraftService.EVENT_DRAFT_EDIT` | Creates a new draft from an active entity. Internally triggers `DRAFT_CREATE`. | +| POST with action `draftActivate` | `DraftService.EVENT_DRAFT_SAVE` | Activates a draft and updates the active entity. Triggers an `CREATE` or `UPDATE` event on the affected entity. | +| n/a | `DraftService.EVENT_DRAFT_CREATE` | Stores a new draft in the database. | You can use these events to add custom logic to the SAP Fiori draft flow, for example to interact with drafts or to validate user data. @@ -140,7 +143,7 @@ It's possible to create and update data directly without creating intermediate d | HTTP / OData request | Event constant name | Default implementation | | ----------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------- | -| POST with `IsActiveEntity: true` in payload | `CqnService.EVENT_CREATE` | Creates the active entity | +| POST with `IsActiveEntity: true` in URI | `CqnService.EVENT_CREATE` | Creates the active entity | | PUT with key `IsActiveEntity=true` in URI | `CqnService.EVENT_CREATE`
`CqnService.EVENT_UPDATE` | Creates or updates the active entity (full update) | | PATCH with key `IsActiveEntity=true` in URI | `CqnService.EVENT_UPDATE` | Creates or updates the active entity (sparse update) | @@ -148,7 +151,7 @@ These events have the same semantics as described in section [Handling CRUD even ::: tip POST Behavior with Direct CRUD -With the 4.8.0 release, CAP Java introduced a mode where `POST` without `IsActiveEntity=true` results in the `CqnService.EVENT_CREATE` (creation of an active entity) for the given entity. This mode is only active when the CDS property `cds.draft.post-active` is set to `true` and the entity is annotated with `@Common.DraftRoot.NewAction`. The annotation value needs to be the name of an unbound action in the same service of the entity. If the entity has a key with the type `UUID`, the action needs no further parameter. Otherwise, the action needs the key values of the entity as parameters. +With the 4.9.0 release, CAP Java introduced a mode where `POST` without explicit `IsActiveEntity` results in the `CqnService.EVENT_CREATE` (creation of an active entity) for the given entity. This mode is automatically active when the entity is annotated with `@Common.DraftRoot.NewAction`, which is generated by the CDS compiler when the `cds_fiori_direct__crud` flag is set. It can also be added via explicit modeling. The annotation value needs to be the name of a bound action in the same service. If the entity has a key of type `UUID`, the action needs no further parameters. Otherwise, the action needs the key values of the entity as parameters. The behavior can be overridden via the `cds.drafts.post-active` property set to `false`. ::: ::: warning Draft locks still apply From ce983054d5080cf96ccafcc0dc490eae4c32ea5f Mon Sep 17 00:00:00 2001 From: Mahati Shankar <93712176+smahati@users.noreply.github.com> Date: Thu, 23 Apr 2026 15:32:21 +0200 Subject: [PATCH 2/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adrian Görler --- java/fiori-drafts.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/fiori-drafts.md b/java/fiori-drafts.md index 7bd1ef8f9..f27fd0eeb 100644 --- a/java/fiori-drafts.md +++ b/java/fiori-drafts.md @@ -79,9 +79,9 @@ Draft-enabled entities have an extra key `IsActiveEntity` by which you can acces | PATCH with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_PATCH` | Updates an existing draft | | DELETE with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_CANCEL` | Deletes an existing draft | | DELETE with key `IsActiveEntity=true` | `CqnService.EVENT_DELETE` | Deletes an active entity *and* the corresponding draft | -| POST with action `draftPrepare` | `DraftService.EVENT_DRAFT_PREPARE` | Empty implementation | -| POST with action `draftEdit` | `DraftService.EVENT_DRAFT_EDIT` | Creates a new draft from an active entity. Internally triggers `DRAFT_CREATE`. | -| POST with action `draftActivate` | `DraftService.EVENT_DRAFT_SAVE` | Activates a draft and updates the active entity. Triggers an `CREATE` or `UPDATE` event on the affected entity. | +| POST with `draftPrepare` action | `DraftService.EVENT_DRAFT_PREPARE` | Empty implementation | +| POST with `draftEdit` action | `DraftService.EVENT_DRAFT_EDIT` | Creates a new draft from an active entity. Internally triggers `DRAFT_CREATE`. | +| POST with `draftActivate` action | `DraftService.EVENT_DRAFT_SAVE` | Activates a draft and updates the active entity. Triggers an `CREATE` or `UPDATE` event on the affected entity. | | n/a | `DraftService.EVENT_DRAFT_CREATE` | Stores a new draft in the database. | You can use these events to add custom logic to the SAP Fiori draft flow, for example to interact with drafts or to validate user data. @@ -151,7 +151,7 @@ These events have the same semantics as described in section [Handling CRUD even ::: tip POST Behavior with Direct CRUD -With the 4.9.0 release, CAP Java introduced a mode where `POST` without explicit `IsActiveEntity` results in the `CqnService.EVENT_CREATE` (creation of an active entity) for the given entity. This mode is automatically active when the entity is annotated with `@Common.DraftRoot.NewAction`, which is generated by the CDS compiler when the `cds_fiori_direct__crud` flag is set. It can also be added via explicit modeling. The annotation value needs to be the name of a bound action in the same service. If the entity has a key of type `UUID`, the action needs no further parameters. Otherwise, the action needs the key values of the entity as parameters. The behavior can be overridden via the `cds.drafts.post-active` property set to `false`. +With the 4.9.0 release, CAP Java introduced a mode where `POST` without a value for `IsActiveEntity` in the payload results in the `CqnService.EVENT_CREATE` (creation of an active entity) for the given entity. This mode is automatically active when the entity is annotated with `@Common.DraftRoot.NewAction`, which is generated by the CDS compiler when the `cds_fiori_direct__crud` flag is set. It can also be added via explicit modeling. The annotation value needs to be the name of a bound action in the same service. If the entity has a key of type `UUID`, the action needs no further parameters. Otherwise, the action needs the key values of the entity as parameters. The behavior can be overridden via the `cds.drafts.post-active` property set to `false`. ::: ::: warning Draft locks still apply From baf123f5e258e54bacde85daec1e796dccdd8dba Mon Sep 17 00:00:00 2001 From: Mahati Shankar <93712176+smahati@users.noreply.github.com> Date: Thu, 23 Apr 2026 15:38:14 +0200 Subject: [PATCH 3/6] cosmetics --- java/fiori-drafts.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/java/fiori-drafts.md b/java/fiori-drafts.md index f27fd0eeb..b9230cb12 100644 --- a/java/fiori-drafts.md +++ b/java/fiori-drafts.md @@ -76,10 +76,10 @@ Draft-enabled entities have an extra key `IsActiveEntity` by which you can acces | POST (no `IsActiveEntity`) on entity *without* a `draftNew` action | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | | POST (no `IsActiveEntity`) on entity *with* a `draftNew` action | `CqnService.EVENT_CREATE` | Creates a new active entity. | | POST with action `draftNew` | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | -| PATCH with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_PATCH` | Updates an existing draft | -| DELETE with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_CANCEL` | Deletes an existing draft | -| DELETE with key `IsActiveEntity=true` | `CqnService.EVENT_DELETE` | Deletes an active entity *and* the corresponding draft | -| POST with `draftPrepare` action | `DraftService.EVENT_DRAFT_PREPARE` | Empty implementation | +| PATCH with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_PATCH` | Updates an existing draft. | +| DELETE with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_CANCEL` | Deletes an existing draft. | +| DELETE with key `IsActiveEntity=true` | `CqnService.EVENT_DELETE` | Deletes an active entity *and* the corresponding draft. | +| POST with `draftPrepare` action | `DraftService.EVENT_DRAFT_PREPARE` | Empty implementation. | | POST with `draftEdit` action | `DraftService.EVENT_DRAFT_EDIT` | Creates a new draft from an active entity. Internally triggers `DRAFT_CREATE`. | | POST with `draftActivate` action | `DraftService.EVENT_DRAFT_SAVE` | Activates a draft and updates the active entity. Triggers an `CREATE` or `UPDATE` event on the affected entity. | | n/a | `DraftService.EVENT_DRAFT_CREATE` | Stores a new draft in the database. | @@ -151,7 +151,7 @@ These events have the same semantics as described in section [Handling CRUD even ::: tip POST Behavior with Direct CRUD -With the 4.9.0 release, CAP Java introduced a mode where `POST` without a value for `IsActiveEntity` in the payload results in the `CqnService.EVENT_CREATE` (creation of an active entity) for the given entity. This mode is automatically active when the entity is annotated with `@Common.DraftRoot.NewAction`, which is generated by the CDS compiler when the `cds_fiori_direct__crud` flag is set. It can also be added via explicit modeling. The annotation value needs to be the name of a bound action in the same service. If the entity has a key of type `UUID`, the action needs no further parameters. Otherwise, the action needs the key values of the entity as parameters. The behavior can be overridden via the `cds.drafts.post-active` property set to `false`. +With the 4.9.0 release, CAP Java introduced a mode where `POST` without a value for `IsActiveEntity` in the payload results in the `CqnService.EVENT_CREATE` (creation of an active entity) for the given entity. This mode is automatically active when the entity is annotated with `@Common.DraftRoot.NewAction`, which is generated by the CDS compiler when the `cds_fiori_direct__crud` flag is set. It can also be added via explicit modeling. The annotation value needs to be the name of a bound action in the same service. If the entity has a key of type `UUID`, the action needs no further parameters. Otherwise, the action needs the key values of the entity as parameters. The behavior can be overridden via the `cds.drafts.post-active` property set to `false`. ::: ::: warning Draft locks still apply From a5b9f478aadabf359dd80a21681b2b1d1659cff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20G=C3=B6rler?= Date: Thu, 23 Apr 2026 16:24:50 +0200 Subject: [PATCH 4/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adrian Görler --- java/fiori-drafts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/fiori-drafts.md b/java/fiori-drafts.md index b9230cb12..fab556f9e 100644 --- a/java/fiori-drafts.md +++ b/java/fiori-drafts.md @@ -143,7 +143,7 @@ It's possible to create and update data directly without creating intermediate d | HTTP / OData request | Event constant name | Default implementation | | ----------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------- | -| POST with `IsActiveEntity: true` in URI | `CqnService.EVENT_CREATE` | Creates the active entity | +| POST with `IsActiveEntity: true` in payload | `CqnService.EVENT_CREATE` | Creates the active entity | | PUT with key `IsActiveEntity=true` in URI | `CqnService.EVENT_CREATE`
`CqnService.EVENT_UPDATE` | Creates or updates the active entity (full update) | | PATCH with key `IsActiveEntity=true` in URI | `CqnService.EVENT_UPDATE` | Creates or updates the active entity (sparse update) | From e1e40275bea74d0fe1591c01c38cddf338927db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20G=C3=B6rler?= Date: Thu, 23 Apr 2026 16:25:36 +0200 Subject: [PATCH 5/6] Update java/fiori-drafts.md --- java/fiori-drafts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/fiori-drafts.md b/java/fiori-drafts.md index fab556f9e..5f476f1a1 100644 --- a/java/fiori-drafts.md +++ b/java/fiori-drafts.md @@ -143,7 +143,7 @@ It's possible to create and update data directly without creating intermediate d | HTTP / OData request | Event constant name | Default implementation | | ----------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------- | -| POST with `IsActiveEntity: true` in payload | `CqnService.EVENT_CREATE` | Creates the active entity | +| POST with `IsActiveEntity: true` in payload | `CqnService.EVENT_CREATE` | Creates the active entity | | PUT with key `IsActiveEntity=true` in URI | `CqnService.EVENT_CREATE`
`CqnService.EVENT_UPDATE` | Creates or updates the active entity (full update) | | PATCH with key `IsActiveEntity=true` in URI | `CqnService.EVENT_UPDATE` | Creates or updates the active entity (sparse update) | From 2218aaabba3fdd65c05710dd912f190368cc9830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20G=C3=B6rler?= Date: Thu, 23 Apr 2026 16:26:00 +0200 Subject: [PATCH 6/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adrian Görler --- java/fiori-drafts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/fiori-drafts.md b/java/fiori-drafts.md index 5f476f1a1..a0fe1058b 100644 --- a/java/fiori-drafts.md +++ b/java/fiori-drafts.md @@ -73,8 +73,8 @@ Draft-enabled entities have an extra key `IsActiveEntity` by which you can acces | HTTP / OData request | Event constant name | Default implementation | | ---------------------------------------------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | POST with `IsActiveEntity=false` in payload | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | -| POST (no `IsActiveEntity`) on entity *without* a `draftNew` action | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | -| POST (no `IsActiveEntity`) on entity *with* a `draftNew` action | `CqnService.EVENT_CREATE` | Creates a new active entity. | +| POST (no `IsActiveEntity`) on entity *without* `draftNew` action | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | +| POST (no `IsActiveEntity`) on entity *with* `draftNew` action | `CqnService.EVENT_CREATE` | Creates a new active entity. | | POST with action `draftNew` | `DraftService.EVENT_DRAFT_NEW` | Creates a new empty draft. Internally triggers `DRAFT_CREATE`. | | PATCH with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_PATCH` | Updates an existing draft. | | DELETE with key `IsActiveEntity=false` | `DraftService.EVENT_DRAFT_CANCEL` | Deletes an existing draft. |