How to force TIdGeneratorNone for the primary index field

Hello. I designed the following table in the datamodeler
UserGUID: TGuid; // ** primary key field
StorageVersion: Integer;
UserData: TBlob;
When the model gets generated, Datamodeler always emits
[Id('FUserGUID', TIdGenerator.Guid)]
atribute for the primary key field. This causes an error when POSTing
the corresponding entity with all fields prefilled by the client:
'Cannot save object of class . The object already has an id, use merge instead.'
The cause of this error is the check in the Objectmanager code:
if FObjects.HasIdValue(Entity) and not EntityType.SafeId.IsUserAssignedId then
raise ECannotSaveWithId.Create(Entity);

When posted, my object HAS UserGUID value prefilled and IsUserAssignedId function returns
false (it returns TRUE only when primary key contains more than one field or the generator
inherits from TIdGeneratorNone)
How do I force the DataModeler to emit TIdGeneratorNone for the UserGUID field?
I would hate to correct this manually in the generated unit. Is there a way to achieve this
directly in the model designer?

I'm sure @wlandgraf will have a better way :grimacing: ...
Meanwhile, you could try this:

procedure OnClassGenerated(Args: TClassGeneratedArgs);
var
  LAttribute : TCodeAttributeDeclaration;
  i : Integer;                                                                          
  LType : string;
begin
  LType := LowerCase(Args.CodeType.Name);
  if (LType = 't_your_type_to_force_lowercase') then begin
    for i := 0 to Args.CodeType.CustomAttributes.Count - 1 do
    begin                                                      
      LAttribute := Args.CodeType.CustomAttributes.Items[i];
      if (LAttribute.Name = 'Id') and (LAttribute.Arguments.Count > 1) then
      begin
          TCodeSnippetExpression(LAttribute.Arguments.Items[1].Value).Value := 'TIdGenerator.None';
      end;                                      
    end;
  end;
end;

Replace 't_your_type_to_force_lowercase' by your entity name in lowercase, like 'tuser' .

1 Like

BTW, the above event must be placed in the script tab, under TMS Aurelius/Export in Data Modeler.

Customization scripts are the way to go, as @Ferrari_Julio mentioned. Here are a couple of more examples to get you inspired:

Thank you both for the solution. The script code works nice and for now this solves my problem.
BTW, is there any reason for raising the exception when an Id field with a generator already has a value when POSTed? One would think that in this case the generator could be simply ignored.

The presence or absence of an ID is key for Aurelius to know if a new ID should be generated, and if it should insert an new record or try to update an existing one.

Thank you for the reply, Wagner. It should insert new record because the method was POST, and the ID is already there so why to generate another one. The only scenario I could think of where the existing ID in POST could be a problem is that it could somehow confuse the ID generator sequence. But I asked just because I was curious. I accept this behavior as a fact, and because it should not cause any problem in my project, I consider the issue solved. Thanks again for your help.

1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.