cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

CAP - Creating multiple draft enabled entities by code fails

a_oezsoy
Explorer
0 Kudos
195

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([...]);

 

View Entire Topic
MattBrightman
Explorer
0 Kudos

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,
          });

 

a_oezsoy
Explorer
0 Kudos

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.