[odb-users] weak pointer gets erased during update

Jeff Waller truthset at gmail.com
Mon Jul 29 01:46:53 EDT 2013


While trying to not complicate the example too much  I have this (see below)

It appears that even when using a session, a weak pointer can disappear
or become invalid.

Note that there is no inverse qualifier, because though the Domain accounts collection
can point to an Account which points back to the Domain as the default domain,
requiring a weak_ptr; this is not necessarily the case.

It's not quite clear to me when a weak_ptr can become invalid.

-Jeff


=======================================
#pragma db object
class Account
{
   friend class odb::access;

   protected:

...
       boost::weak_ptr<Domain> default_domain;
      #pragma db get(getAKA) set(setAKA)
…
}


#pragma db object
class Domain
{
   friend class odb::access;

   protected:

...
        std::map< std::string,boost::shared_ptr<Account> > accounts;
…
}


During this section of code:

         boost::shared_ptr<Domain> targetDomain = Domain::getDomainForAccount(soap_wsse_get_Username(this));
         ephemeralAccount = Account::createAccount(theLogin_p,"ephemeral",targetDomain->getDomainName().c_str());

         {
            ExclusiveDBAccess access;
            database *db = access.getTheDB();
            transaction t(db->begin());

            ephemeralAccount->setAKA(aGrantor_p);
#1--->    db->update(ephemeralAccount);
#2--->    t.commit();
         }



At point 1 the db looks like this:

sqlite> select * from Account;
6|kE48qbpEh5L95pc|0|1|2|2|

but at time 2 (after commit)
6|kE48qbpEh5L95pc|0||2|2|1

But it works if the code is changed to:


         ephemeralAccount = Account::createAccount(theLogin_p,"ephemeral");
         boost::shared_ptr<Domain> defaultDomain = Domain::getDomainForAccount(soap_wsse_get_Username(this));

         {
            ExclusiveDBAccess access;
            database *db = access.getTheDB();
            transaction t(db->begin());

            ephemeralAccount->setAKA(aGrantor_p);
            ephemeralAccount->setDefaultDomain(defaultDomain);
            defaultDomain->addAccount(ephemeralAccount);
            db->update(ephemeralAccount);
            db->update(defaultDomain);
            t.commit();
         }
      }

but even at #2, 

gdb) print *ephemeralAccount
$2 = (Account &) @0x8bdc90: {_vptr.Account = 0x5bc670, id = 8, username = "6|kE48qbpEh5L95pc", is_superuser = false, default_domain = {px = 0x8c3bb0, pn = {
      pi_ = 0x8c5470}}, profile = {px = 0x8bdc30, pn = {pi_ = 0x8be950}}, authenticator = {px = 0x8bc640, pn = {pi_ = 0x8bd8a0}}, aka = {px = 0x8bea40, pn = {
      pi_ = 0x8bd450}}, roles = std::vector of length 0, capacity 0}







More information about the odb-users mailing list