Error in SQLite3

Hi,


I try save procedure in ObjectManager.
Basically, it's ok.
But, Unique key in Model throw Exception Unique constraint failed in [FireDAC][Phys][SQLite]
And, after try other or same value to save throws Exception like this
EEngineInternalError with message 'OPF Internal error: Cannot add in object map - id already exists.'

This error not raised in PostgreSQL database.

How can i handle this?

regards.

Hi,

You can clear the id of the object before saving it again:


MyEntity .Id := 0;




Hi, Thank you for answer~

My Id property is read-only.
and, alway insert new entity object.

like this ( - this is pseudo )

procedure btnAddClick(Asender: Tobject);
var
vUserData : TUserData;
begin
vUserData := CreateUserData;
Manager.Save(vUserData);
end;

function CreateUserData: TUserData;
begin
result = TUserData.Create;
end;

in SQLite3  First time Manager.Save throws FireDAC Unique error.
and after always throws ID error.

Regards.

What is the mapping of your TUserData class?

Since it's SQLite, can you create a simple project that reproduces the problem and send it to us?
Hi,

I found reason.

=============== Entities ======================

TMoney = class;

  [Entity, Automapping]
  TUserData = class
  private
    FId                         : Int64;
    [Column('UserName', [TColumnProp.Required, TColumnProp.Unique])]
    FUserName                   : Nullable<string>;
    [Column('NickName', [TColumnProp.Required, TColumnProp.Unique])]
    FNickName                   : Nullable<string>;
    [Association([TAssociationProp.Required], CascadeTypeAll)]
    [JoinColumn('ID_MONEY', [TColumnProp.Required])]
    FMoneyData                  : Proxy<TMoney>;
  protected
    function                    GetMoneyData: TMoney;
    procedure                   SetMoneyData(const AValue: TMoney);
  public
    property                    Id: Int64 read FId;
    property                    UserName: Nullable<string> read FUserName write FUserName;
    property                    NickName: Nullable<string> read FNickName write FNickName;
    property                    MoneyData: TMoney read GetMoneyData write SetMoneyData;
  end;

  [Entity, Automapping]
  TMoney = class
  private
    FId                         : Int64;
    FMoneyValue                 : Int64;
  public
    property                    Id: Int64 read FId;
    property                    MoneyValue: Int64 read FMoneyValue;
  end;


==================== Code ===================

procedure TfrmMain.Button1Click(Sender: TObject);
var
  vUserData                   : TUserData;
begin
  vUserData                   := CreateUserData;

  try
    FManager.Save(vUserData);
  except
    vUserData.MoneyData.Free;
  end;
end;

function TfrmMain.CreateUserData: TUserData;
begin
  Result                      := TUserData.Create;
  Result.UserName             := Edit1.Text;
  Result.NickName             := Edit2.Text;
  Result.MoneyData            := TMoney.Create;
end;
============================================

First time in Button1 Click, it's ok.
Second time with same UserName or NickName property raise 'Unique .....' Exception
Third time any property raise 'OPF Internal error: Cannot add in object map - id already exists'.




That's expected. In the second save, TMoney is saved (because of cascade), and a new TMoney object with id = 2 is added to the manager. But saving of TUserData fails because of unique key. When you try to save for the third time, it will try to save TMoney again, which will come again with an id of 2. Then the manager tries to add that object in the internal list, but another TMoney with id equals 2 is already there.

You should clear the manager before trying to save TUserData again. Or, at least, try to save the same tree. Currently every time you click the button you create a new instance o TUserData, with a new instance of TMoney, etc.. Either retry to save the same object tree, or completely clear the manager if you are going to save a new object tree anyway.