Inheritance

Hello!

I have looked at the manual discussing inheritance strategies etc. and I need to inherit one table from another.
This is what I currently have:

[Entity]
  [Table('CMTUNITAORGANIZZATIVE')]
  [Id('FID_CMTOGGETTI', TIdGenerator.None)]
  [Inheritance(TInheritanceStrategy.JoinedTables)]
  TCMTUNITAORGANIZZATIVE = class( TCMTOGGETTI )
  private
    [Association([TAssociationProp.Lazy, TAssociationProp.Required], CascadeTypeAll - [TCascadeType.Remove])]
    [JoinColumn('ID_CMTOGGETTI', [TColumnProp.Required], 'ID')]
    [ForeignKey('FK_CMTUNITAORGANIZZATIVE_CMTOGGETTI')]
    FID_CMTOGGETTI: Proxy<TCMTOGGETTI>;

Which inherits from:

[Entity]
  [Table('CMTOGGETTI')]
  [UniqueKey('CODICE, ID_CMTTIPIOGGETTO, DATA_INIZIO, DATA_FINE, ID_PADRE')]
  TCMTOGGETTI = class( TIDNullableDescription1000WithLog )
  private
    [Column('CODICE', [TColumnProp.Required], 50)]
    FCODICE: string;

    [Column('ID_CMTTIPIOGGETTO', [TColumnProp.Required])]
    FID_CMTTIPIOGGETTO: Integer;

which inherits from:

[AbstractEntity]
  TIDNullableDescription1000WithLog = class( TIDLogModelBase )
  strict private
    [Column('DESCRIZIONE', [], 1000)]
    FDescrizione: Nullable<string>;
    procedure SetDescription(const Value: Nullable<string>);
  public
    property Descrizione: Nullable<string> read FDescrizione write SetDescription;
  end;

Which inherits from:

[AbstractEntity]
  TIDLogModelBase = class( TIDModelBase, IDataLog )
  strict private
    [Column('USER_INS', [], 50)]
    FUSER_INS: Nullable<string>;

    [Column('DATA_INS', [])]
    FDATA_INS: Nullable<TDateTime>;

And so on, there is another one for the ID:

[AbstractEntity]
  [Id('FID', TIdGenerator.IdentityOrSequence)]
  TIDModelBase = class( TModelBase )
  strict private
    [Column('ID', [TColumnProp.Required, TColumnProp.NoInsert, TColumnProp.NoUpdate])]
    FID: Integer;

When I try to load a list of TCMTUNITAORGANIZZATIVE, however, I get an AV.
This is the code I am using:

procedure TForm1.Button1Click(Sender: TObject);
var
  ObjMgr: TObjectManager;
  List : TObjectList<TCMTUNITAORGANIZZATIVE>;
  Obj: TCMTUNITAORGANIZZATIVE;
  Crit : TCriteria<TCMTUNITAORGANIZZATIVE>;
begin
  Crit := ObjMgr.Find<TCMTUNITAORGANIZZATIVE>;
  List := Crit.List;
  for Obj in List do
  begin
    ListBox1.Items.Add(Obj.Descrizione);
  end;
end;

The AV happens here:

function TDictionary<K,V>.GetKeys: TKeyCollection;
begin
  if FKeyCollection = nil then
    FKeyCollection := TKeyCollection.Create(Self);
  Result := FKeyCollection;
end;

The call stack is this:

Any suggestion on what may be happenning here?

Thanks!

Your hierarchy is wrong. The Inheritance attribute must be in the root concrete entity class, not in the descendant.

In your example, the Inheritance attribute should be in class TCMTOGGETTI.
Then class TCMTUNITAORGANIZZATIVE should have a PrimaryJoin attribute.

Also, you can't have two ID's in the same hierarchy. You are defining Id in class TCMTUNITAORGANIZZATIVE and also in class TIDModelBase. That is not possible.

Ooooh okay that makes sense!

I will rework that and see if it works better :P I'll keep you posted.

Hey!

I am still clearly doing it wrong somehow but I have changed the two main classes in this way:

[Entity]
  [Table('CMTOGGETTI')]
  [UniqueKey('CODICE, ID_CMTTIPIOGGETTO, DATA_INIZIO, DATA_FINE, ID_PADRE')]
  [Inheritance(TInheritanceStrategy.JoinedTables)]
  TCMTOGGETTI = class( TIDNullableDescription1000WithLog )
  private
    [Column('CODICE', [TColumnProp.Required], 50)]
    FCODICE: string;

    [Column('ID_CMTTIPIOGGETTO', [TColumnProp.Required])]
    FID_CMTTIPIOGGETTO: Integer;

And:

[Entity]
  [Table('CMTUNITAORGANIZZATIVE')]
  [PrimaryJoinColumn('FID_CMTOGGETTI')]
//  [Id('FID_CMTOGGETTI', TIdGenerator.None)]
  TCMTUNITAORGANIZZATIVE = class( TCMTOGGETTI )
  private
    [Association([TAssociationProp.Lazy, TAssociationProp.Required], CascadeTypeAll - [TCascadeType.Remove])]
    [JoinColumn('ID_CMTOGGETTI', [TColumnProp.Required], 'ID')]
    FID_CMTOGGETTI: Proxy<TCMTOGGETTI>;
    
    [Column('INDIRIZZO', [], 500)]
    FINDIRIZZO: Nullable<string>;

Still getting an AV though!

Thoughts?

Thanks!

Can you please send us a project reproducing the issue, so we can better analyze it?

I can try to do so later because right now I am having one more issue that I think I have seen before.