2025 May 14 9:27 AM - edited 2025 May 14 12:03 PM
Hello,
I am having some trouble with creating multiple records of a draft-enabled entity.
I have 2 entities which have a 1-n composition between each other (it is only a one-way relationship):
entity ParentEntity : cuid, managed {
...
Children : Composition of many ChildEntity on Children.parentId = ID;
}
entity ChildEntity : cuid, managed {
...
value : String not null;
parentId : UUID not null;
}
I have enabled drafts for the parent entity in my service.
using db from ...;
service Service {
.draft.enabled
entity ParentEntity as projection on db.ParentEntity;
entity ChildEntity as projection on db.ChildEntity;
}
Now in my code, I want to create multiple children entities. In CAP v7, this was possible by simply creating the child entity records and specifying the key of the parent.
// this used to work in CAP v7
const query = INSERT.into('ChildEntity').entries([
{..., value: 'abc', parentId: ...},
{..., value: 'def', parentId: ...},
...
]);
await service.run(query);
However, with CAP v8 a restriction is added, that draft-enabled entities can only be modified by their root entities. My issue is, that this doesn't allow creation of multiple records.
// WORKS - creates a single record
const query = INSERT.into('ParentEntity[<ID>].Children').entries(
{..., value: 'abc', parentId: <ID>}
);
// DOESN'T WORK - attempts o create multiple records
const query = INSERT.into('ParentEntity[<ID>].Children').entries([
{..., value: 'abc', parentId: <ID>},
{..., value: 'def', parentId: <ID>},
...
]);
// OR
const children = [...]
const query = INSERT
.into('ParentEntity[<ID>].Children')
.entries(...children);
Our workaround is currently running multiple queries asynchronously (with await Promise.all). Is this behaviour intended and if yes, there a different way of creating multiple draft-enabled records?
Thank you for your help.
Atakan
PS: I am experiencing this issue on @SAP/cds v8.8.3.
UPDATE 1:
I realized slightly after, that the same problem also applies for the parent entity in this case. So creation of multiple records is not available for any draft-enabled entities.
// ALSO DOESN'T WORK
const query = INSERT.into('ParentEntity').entries([...]);
Request clarification before answering.
If just need to insert entries and don't need `Draft workflow` there is a bypass draft setting. Alternatively this setting can be set on entity level with `@odata.draft.bypass` annotation.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Have you taken a look at this, specifically: Programmatic Invocation of Draft Actions
https://cap.cloud.sap/docs/node.js/fiori#programmatic-invocation-of-draft-actions
Maybe this could help:
await srv.new(MyEntity.drafts, data) // create new draft
I have created draft entities from children before. See the action fillEntities here
await this.create(ServiceAuth.drafts).entries({
to_ServiceRole_RoleUUID: RoleUUID,
AuthType_AuthorisationType: req.data.AuthorisationType,
DraftAdministrativeData_DraftUUID:
entity.DraftAdministrativeData_DraftUUID,
AuthEntity_EntityUUID: entity.EntityUUID,
});
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi, thank you for your response. I did see the section about the draft actions. However, I don't think it helps my problem. I would like to create multiple records in one query. Since I would need to save my drafts after (with srv.save), I still need multiple calls (one per save operation).
I checked your example (thanks for providing me one). But you also ran a for loop for all records and ran one create query per record. In non draft entities you can just create multiple records with one query. This is what I would like to achieve.
Note: I know that I can use manual transactions (with srv.tx) to commit all queries at once, but I first want to ensure that creating everything in one query doesn't work.
User | Count |
---|---|
33 | |
22 | |
17 | |
8 | |
7 | |
5 | |
4 | |
4 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.