[odb-users] Re: Recursive Loading Issue with Mutual Aggregation in
ODB Classes
xuewen wang
xuewen.ok at gmail.com
Fri Aug 2 23:23:54 EDT 2024
Sorry, all,
It is my fault that I used the wrong inverse(id) keyword; it used the
second class's id but not the inverse member id.
Best regards...
---- Sean Wang (Xuewen Wang), Beijing, China.
On Fri, Aug 2, 2024 at 11:21 PM xuewen wang <xuewen.ok at gmail.com> wrote:
> Dear ODB Development Team,
>
> I am writing to report a potential issue with the ODB ORM system when two
> model classes include or aggregate each other. This mutual aggregation can
> lead to recursive loading problems when querying records from the database.
>
> ### Example Scenario
>
> Consider the following two classes, `Person` and `Address`, where each
> `Person` has an `Address` and each `Address` has a `Person`.
>
> #### Person.hxx
> cpp
> #pragma once
>
> #include <memory>
> #include <odb/core.hxx>
> #include "Address.hxx"
>
> #pragma db object
> class Person
> {
> public:
> Person() = default;
> Person(const std::string& name, std::shared_ptr<Address> address)
> : name_(name), address_(address) {}
>
> const std::string& name() const { return name_; }
> std::shared_ptr<Address> address() const { return address_; }
>
> private:
> friend class odb::access;
>
> #pragma db id auto
> unsigned long id_;
> std::string name_;
>
> #pragma db not_null
> std::shared_ptr<Address> address_;
> };
> #### Address.hxx
> cpp
> #pragma once
>
> #include <memory>
> #include <odb/core.hxx>
> #include "Person.hxx"
>
> #pragma db object
> class Address
> {
> public:
> Address() = default;
> Address(const std::string& street, std::shared_ptr<Person> person)
> : street_(street), person_(person) {}
>
> const std::string& street() const { return street_; }
> std::shared_ptr<Person> person() const { return person_; }
>
> private:
> friend class odb::access;
>
> #pragma db id auto
> unsigned long id_;
> std::string street_;
>
> #pragma db not_null
> std::shared_ptr<Person> person_;
> };
> ### Issue
>
> When querying a `Person` from the database, ODB will try to load the
> associated `Address`. While loading the `Address`, ODB will again try to
> load the associated `Person`, leading to a recursive loop.
>
> ### Query Example
> cpp
> #include <odb/database.hxx>
> #include <odb/transaction.hxx>
> #include <odb/sqlite/database.hxx>
> #include "Person.hxx"
> #include "Person-odb.hxx"
> #include "Address.hxx"
> #include "Address-odb.hxx"
>
> int main()
> {
> std::shared_ptr<odb::database> db(new odb::sqlite::database("test.db",
> SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE));
>
> // Start a transaction
> odb::transaction t(db->begin());
>
> // Query a person by id
> std::shared_ptr<Person> person(db->load<Person>(1));
>
> // Commit the transaction
> t.commit();
>
> // Access the person's address
> std::shared_ptr<Address> address = person->address();
>
> return 0;
> }
> In this example, loading a `Person` will recursively load the `Address`,
> which will again try to load the `Person`, causing a recursive call.
>
> ### Request
>
> Could you please look into this issue and provide a resolution or
> workaround?
>
> Thank you for your attention to this matter.
>
> Best regards,
>
More information about the odb-users
mailing list