Lazy initialization of child Lists no longer seems to be working in latest Tip Branch

Issue #73 closed
Todd Flora created an issue

Hello,

I have the following Parent Object

type
  [Entity]
  [Table('PUB_SUBSCRIBER', '')]
  [Sequence('Select GetSid as Sid from dual')]
  TPubSubscriber = class
  private
    [Column('SID',[cpRequired,cpPrimaryKey,cpDontInsert,cpDontUpdate,cpNotNull ],19,0)]
    FSid: Int64;
    [OneToMany(False, [ckCascadeAll])]
.
.
.
    FSubscriptions: Lazy<IList<TPubSubscription>>;
    function GetSubscriptions: IList<TPubSubscription>;
    function GetSid: String;
    procedure SetSid(const Value: String);
  public
    constructor Create;
    property Sid: String read GetSid write SetSid;
.
.
. 
   property Subscriptions: IList<TPubSubscription> read GetSubscriptions;
  end;

And the Child entity looks like this:

[Entity]
  [Table('PUB_SUBSCRIPTION', '')]
  [Sequence('Select GetSid as Sid from dual')]
  TPubSubscription = class
  private
    [Column('SID',[cpRequired,cpPrimaryKey,cpDontUpdate,cpDontInsert,cpNotNull],19,0)]
    FSid: Int64;
.
.
. 
   [OneToMany(False, [ckCascadeAll])]
    FSubscriptionEvents : Lazy<IList<TPubSubscriptionEvent>>;
    function GetPubSubscriptionEvents: IList<TPubSubscriptionEvent>;
    function GetSid: String;
    procedure SetSid(const Value: String);
  public
    constructor Create;
    property Sid: String read GetSid write SetSid;
.
.
.
    [ForeignJoinColumn('SUBSCRIBER_SID', 'PUB_SUBSCRIBER', 'SID', [fsOnDeleteCascade, fsOnUpdateCascade])]
    [Column('SUBSCRIBER_SID',[cpRequired,cpNotNull],19,0)]
    property SubscriberSid: Int64 read FSubscriberSid write FSubscriberSid;
 end;

Before the latest changes you made for Foreign Key inserts this used to get all the children into the list. But now the Subscriptions list comes back blank, even though the database has child records.

Thanks for any help on what I may be doing wrong.

Comments (6)

  1. Linas Naginionis

    Can you give more information (or show some code example) when you are not getting children in the list?

  2. Todd Flora reporter

    Very simple code.

    I have this function to get a session:

    function TForm2.GetSession : TSession;
    begin
      if not Assigned(Session) then
      begin
        {Setup a FireDac Connection}
        FDConnection := TFDConnection.Create(nil);
        FDConnection.ConnectionName := 'OracleConnection1';
        FDConnection.ConnectionString := edConnectString.Text;
        FDConnection.Params.Add('CharacterSet=utf8');
        FDConnection.Connected := True;
        {Wrap the connection with a Marshmallow Connection}
        Connection := TConnectionFactory.GetInstance(dtFiredac, FDConnection);
        Connection.SetQueryLanguage(TQueryLanguage.qlOracle);
        Session := TSession.Create(Connection);
      end;
      Result := Session;
    end;
    

    And then this simple code to all PubSubscribers and serialize them to a memo component.

    procedure TForm2.btnGetClick(Sender: TObject);
    var
      Subscribers : IList<Prism.Model.PubSubscriber.TPubSubscriber>;
    begin
      {Get all rows from Subscriber}
      Subscribers := GetSession.FindAll<Prism.Model.PubSubscriber.TPubSubscriber>;
      SetSerializedPayload(Subscribers);
    end;
    
    procedure TForm2.SetSerializedPayload(Payload : IList<Prism.Model.PubSubscriber.TPubSubscriber>);
    begin
      Serializer.AsObject := Payload;
      Serializer.Formatted := True;
      memo1.Lines.Text := Serializer.AsJSON;
    end;
    

    This code worked before the latest update.

    Here is the decl code for the variables.

     protected
        { Protected declarations }
        FDConnection : TFDConnection;
        Connection : IDBConnection;
        Session : TSession;
        Serializer : ISerializer<IList<Prism.Model.PubSubscriber.TPubSubscriber>>;
        function GetSession : TSession;
        function GetSerializedPayload : IList<Prism.Model.PubSubscriber.TPubSubscriber>;
        procedure SetSerializedPayload(Payload : IList<Prism.Model.PubSubscriber.TPubSubscriber>) ;
    

    The serializer loops through all the attributes including the collection attribute. When it hits this attribute the lazy initialization should be working but it does not seem to be.

  3. Linas Naginionis

    @Toddflora I cannot reproduce this issue in my tests. Are you sure your TPubSubscriber constructor isn't initializing FSubscriptions? After my recent commit, framework checks lazy values of relationship columns. OneToMany relationships will be loaded only if lazy value isn't created.

  4. Linas Naginionis

    After some discussions I've reverted the old behaviour (no additional checks if lazy values are created) in the latest commit. Hope this will solve your issue.

  5. Todd Flora reporter

    Awesome it is working again. Thanks so much.

    BTW: We have looked at EntityDac and Aurelius and despite the fact that Marshmallow does not have an editor per say, Marshmallow is the best product for our application. Do you have a release date for Version 1?

  6. Stefan Glienke repo owner

    Hey Todd and thanks for your testing. If all works as planned Spring 1.2 will be released this spring.

  7. Log in to comment