cap-js / cds-dbs

Monorepo for SQL Database Services for CAP
https://cap.cloud.sap/docs/
Apache License 2.0
37 stars 11 forks source link

@cap-js/hana - Problem with insert on tables with columns with default null - they are filled with current timestamp #773

Closed DinoWinter closed 1 month ago

DinoWinter commented 3 months ago

Insert a row in a table with columns with default null leads to current timestamps in these columns.

  1. Create a table with some columns with a default null and deploy to HANA
    
    namespace my.test;

using { managed } from '@sap/cds/common';

entity Test : managed { key id : UUID; description : String(255); anotherText : String(255) default null; loggedAt : Timestamp default null;

};


> 2. Create a service and run local:
```cds
using {my.test as test} from '../db/test';

service TestService @(path : '/test')  {
    entity Test @(restrict : [{grant : [
        'READ',
        'WRITE'
    ]}]) as projection on test.Test;
}
  1. Create a new row in the table with only a description set:
    
    POST http://localhost:4004/test/Test
    Content-Type: application/json

{ "description": "a new description" }


> The response is:

HTTP/1.1 201 Created X-Powered-By: Express X-Correlation-ID: 7f46ab8b-41b2-4e92-b392-7be6e985075b OData-Version: 4.0 location: Test(87bb7c82-c059-4ebe-aa9a-62becc5cc04e) Content-Type: application/json; charset=utf-8 Content-Length: 328 Date: Mon, 05 Aug 2024 14:33:24 GMT Connection: close

{ "@odata.context": "$metadata#Test/$entity", "anotherText": "2024-08-05T14:33:24.882Z", "createdAt": "2024-08-05T14:33:24.882Z", "createdBy": "privileged", "description": "a new description", "id": "87bb7c82-c059-4ebe-aa9a-62becc5cc04e", "loggedAt": "2024-08-05T14:33:24.882Z", "modifiedAt": "2024-08-05T14:33:24.882Z", "modifiedBy": "privileged" }


> I found the problem in the @cap-js/hana
It seems to be in the file HANAService.js in the line 1040: const defaultValue...:
```js
        if (!isUpdate) {
          const d = element.default
          if (d && (d.val !== undefined || d.ref?.[0] === '$now')) {
            const defaultValue = d.val ?? (cds.context?.timestamp || new Date()).toISOString()
            managed = typeof defaultValue === 'string' ? this.string(defaultValue) : defaultValue
          }
        }

If the colunns has a default value of null then d.val is null and the date is set as the value for the column.

Maybe there is someone who can fix this?

This is my first time I open an issue and I hope I described it as expected.

Details about your project

I created everything with Business Application Studio as an MTA.

Text
@cap-js/asyncapi 1.0.2
@cap-js/hana 1.1.1
@cap-js/openapi 1.0.4
@sap/cds 8.1.0
@sap/cds-compiler 5.1.0
@sap/cds-dk 8.1.0
@sap/cds-dk (global) 8.1.0
@sap/cds-fiori 1.2.7
@sap/cds-foss 5.0.1
@sap/cds-mtxs 2.0.3
@sap/eslint-plugin-cds 3.0.4
Node.js v20.12.0
johannes-vogel commented 3 months ago

Hi @DinoWinter,

I don't think default null makes much sense. If you omit that the default is anyway null on the db. Could you double check that?

DinoWinter commented 3 months ago

Hi @johannes-vogel, you're right that the default null is not needed in the CDS table definition. It changes nothing in the table created on the HANA-DB. If I remove the default null from the CDS it works as expected. But I have old projects where the default null is explicitly written in the CDS files and it works without problems now. So I have to check all CDS files if i move to the new cap-js/hana because it does not handle it as expected/before? Ok, its tedious but seems to be necessary :) Best regards, Dino