Problem with associations between entities in different units

Hi
We have a problem with entities that has 'bidirectional' relationsships. We want to store each entity in a separate unit but then we cannot map a biderectional relationship without the circular referencs error.

We could omit the reference from the child to the mother but then we cant pass the child as a parameter and then access the mother.
consider the entities below where the mother has a many valued association to the child and the child doesnt have any association to the mother but we still want to have the mother id column (present in the child table in database) mapped as a pure integer.

This doesnt work thus aurelius when building the SQL adds the Mum column twice.

unit uEntityMother
 uses
    unit uEntityChild 

  TMother = class(TObject)
  private
    [Column('MumID' , [])]
    fMumId: integer;

    [ManyValuedAssociation([], CascadeTypeAllRemoveOrphan)]
    [ForeignJoinColumn('Mum', [TColumnProp.Required])]
    FChildren: TList<TChild>;

  public
    constructor Create;
    destructor Destroy; override;
    property MumId: Integer read fMumId;
    property Children: TList<TChild> read FChildren write FChildren;
  end;
unit uEntityChild  

 [Entity]

  TChild = class(TObject)
  private
    [Column('ChildID' , [])]
    fChildId: integer;

    [Column('Mum' , [])]
    FMum: Integer;

  public
    property ChildId: Integer read fChildId;
    property Mum: Integer read FMum write FMum;
  end;

The SQL will look something like this

CREATE TABLE CHILD ( ChildID INTEGER NOT NULL, Mum INTEGER NOT NULL, Mum INTEGER NOT NULL, CONSTRAINT PK_CHILD PRIMARY KEY (ChildID))

Thus containing the column Mum twice tough the many valued association in TMother.FChildren and the column TChild.FMum both maps to the same table and column in the database.

Is there anyway around this problem?

We really want to avoid putting a lot of entites in the same unit just to be able to map realations.

//Best regards

Unfortunately, no.
This is a Delphi limitation. If you have class A referencing class B, and class B referencing class A, they have to be in the same unit. No way to do it different, regardless if the classes are Aurelius entity classes or just Delphi regular classes.

There is one way that will keep your unit small.

You could put all data Fields in Abstract-Entities and put these in seperate Units.
So only the association (and many-valued assoc) Fields would appear in your big unit.

for example:

unit uEntityMotherBase

  [AbstractEntity]
  TMotherBase = class(TObject)
  private
    [Column('MumID' , [])]
    fMumId: integer;
  public
    property MumId: Integer read fMumId;
  end;
unit uEntityChildBase  

  [AbstractEntity]
  TChildBase = class(TObject)
  private
    [Column('ChildID' , [])]
    fChildId: integer;
  public
    property ChildId: Integer read fChildId;
  end;
unit uEntityAssocs
 uses
    unit uEntityMotherBase, uEntityChildBase;
  
  TChild = class;
  [Entity]
  TMother = class(TMotherBase )
  private
    [ManyValuedAssociation([], CascadeTypeAllRemoveOrphan)]
    [ForeignJoinColumn('Mum', [TColumnProp.Required])]
    FChildren: TList<TChild>;
  public
    constructor Create;
    destructor Destroy; override;
    property Children: TList<TChild> read FChildren write FChildren;
  end;

  [Entity]
  TChild= class(TChildBase )
  private
    [JoinColumn('Mum' , [])]
    FMum: TMother ;
  public
    property Mum: Integer read FMum write FMum;
  end;
1 Like

Hi Again.

To clarify a bit as I have mapped the entities now there are no compile errors. In the Child class I have mapped the mum as a plain integer not an association.

Both the TMother.Children and the TChild.Mum references the same column in the Child table in the database.

But when Aurelius builds the SQL query it ads the Mum column twice. if Aurelius hadnt done that this construction would have worked out for us.

Is this behaviour by design or is it a bug? Seems a bit strange that two entities reffering the same column in the database should make the SQL builder add the column twice. Which it does both when creating the table in the DB and when making insert statement.

//Best regards.

The circular reference issue is beyond Aurelius scope.

I don't know if you really meant distinct formal units, or if you just want to avoid many entities in the same file, maybe for easier code maintenance. If that's the case, you should use $include. (You would need 2 include files per entity - one for interface, and other for implementation).

1 Like

It's a behavior. If you (wrongly) mapped a column twice, it will appear twice in the SQL.