Description
In CDS 10, the return values of generic CRUD operations are aligned with their semantic meaning. UPDATE now returns the number of affected rows as a plain integer instead of the updated entity object. INSERT and UPSERT now return an array of key objects (e.g. [{ ID: 1 }]) rather than the inserted entity. Code that reads entity properties from the return value of these operations will receive undefined at runtime. This affects both the fluent query builder forms (INSERT.into(...), UPDATE.entity(...)) and the service-level shorthand (srv.insert(...), srv.update(...)).
How to Check
- [ ] Search for
awaitexpressions whose result is assigned to a variable and then accessed via property notation — e.g.const result = await srv.update(...)followed byresult.someProperty. - [ ] Search for code that passes the return value of
UPDATE,INSERT, orUPSERTto a function expecting an entity object or a typed CAP entity type. - [ ] Check tests and assertions that compare the full shape of the return value from these operations (e.g.
expect(result).toMatchObject({ ID: 1, name: 'foo' })). - [ ] Search for the patterns:
await $EXPR.update(...),await $EXPR.insert(...),await $EXPR.upsert(...),await UPDATE(...),await INSERT(...),await UPSERT(...).
Migration Steps
For each
UPDATEcall whose return value is used, replace property access with a fresh read or restructure the code to not depend on the return value:diff- const updated = await srv.update(Books, { ID: 1 }).with({ stock: 99 }); - console.log(updated.title); // was entity object, now integer + const affectedRows = await srv.update(Books, { ID: 1 }).with({ stock: 99 }); + const updated = await srv.read(Books, 1); + console.log(updated.title);For each
INSERTorUPSERTcall whose return value is used as an entity object, update the code to treat the result as an array of key objects:diff- const book = await srv.insert(Books).entries({ title: 'New Book', stock: 10 }); - console.log(book.title); // was full entity, now array of keys + const keys = await srv.insert(Books).entries({ title: 'New Book', stock: 10 }); + // keys is e.g. [{ ID: 42 }] — fetch full entity if needed: + const book = await srv.read(Books, keys[0].ID); + console.log(book.title);Update test assertions to match the new shapes:
diff- expect(result).toMatchObject({ ID: 1, title: 'Updated' }); + expect(result).toBe(1); // UPDATE: affected row countdiff- expect(result).toMatchObject({ ID: 42, title: 'New Book' }); + expect(result).toEqual([{ ID: 42 }]); // INSERT/UPSERT: array of keys
Notes
The change applies to direct database service calls as well as application service calls that are not overridden by custom handlers. Custom on('UPDATE', ...) handlers that explicitly return an entity object are unaffected — they continue to return whatever the handler returns.