cancel
Showing results for 
Search instead for 
Did you mean: 

SAP CAP @assert.unique does not work with non-key field

merveguel
Participant

Hello gurus,

I am using below entity in a list report fiori elements application. I would like to make the product field unique by itself where the user can not enter/save the same product more than one time. I tried to use @assert.unique annotation however it did not make any change during the save function. Can anyone guide/explain (to) me on why it does not work?

@assert.unique: {productUnique: [product]} 

@cds.autoexpose 

entity Product : managed 

{ 

key id        : UUID; 

product       : String; 

productDetail : Composition of many 

{ 

key id               : UUID; 

plant            : String; // IWERK 

planGroupKey     : String; // STDNR 

planGroupCounter : String; // STDAL 

} 

}

Thanks in advance,

Merve

Willem_Pardaens
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Merve,

This should work how you have it. Just try with a POST call to create a record with the same product name twice and you will see it blocks it.

vansyckel
Advisor
Advisor
0 Kudos

Hi Merve,

Did you redeploy? Uniqueness is enforced on the database.

Best,
Sebastian

merveguel
Participant
0 Kudos

Hi willem.pardaens and vansyckel

First of thank you for your replies.

willem.pardaens I already tried with POST call but did not work during testing on BAS.

vansyckel I thought it should have been already working fine on BAS, after your comment I have deployed (during deployment interestingly the pipeline did not let me to have the annotation in data-schema.cds and forced me to append it in the service cds, see as follows). However the result did not changed. Could that be a bug related with having the table (entity) and field name same?

    @assert.unique: { productUnique: [ product ]} 
    entity Product        as projection on dataservice.Product;

Willem_Pardaens
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Merve,

To my understanding you are creating a Draft entity here, which is not directly created in the Product table but in the Product_drafts table. I guess the assertion is only enforced when you save/activate the draft later on.

I would try and use the After New(?) handler on the Product.drafts entity to validate the user input (https://cap.cloud.sap/docs/node.js/fiori#draft-support).

merveguel
Participant
0 Kudos

Hi willem.pardaens

Thank you for the explanation, with an event handler I was able to throw the error message that I wanted to. Only one additional question: I wanted to throw the error in the field level instead of a pop-up dialog. That should be technically possible with "in/" prefix addition, however again in my case it didnt work (I am assuming something to do with drafts again). Would you have any comment on that?

If I am lucky enough 🙂 maybe david.kunz2 makes a comment on that since I benefited his reply in this question.

this.on("NEW", "Product", async function (req, next) 
{ 
let oProduct; 
oProduct = await SELECT.from(Product).where`product=${req.data.product}`; 
// If the product is already in the Product table, then do not let the user duplicate it. 
if (oProduct.length > 0) 
{ 
req.reject(429, `The ${req.data.product} product already maintained.`, 'in/product'); 
return; 
} 
await next(); 
}); 
}; 
vansyckel
Advisor
Advisor

Hi Merve, Willem,

  1. Drafts shall not be validated until they are activated. Hence, both runtime and compiler do not check.
  2. The NEW event creates a new, initially empty draft -- except for the ID. Use PATCH if you want to validate user input.
  3. You need to return the result of next().
  4. Sorry, can't help regarding the "in/" stuff.

Best,
Sebastian

Accepted Solutions (0)

Answers (0)