[odb-users] Proper way to reload QLazySharedPointer objects within a session

Boris Kolpackov boris at codesynthesis.com
Wed Jun 6 09:50:38 EDT 2012


Hi Rene,

Rene Jensen <rene at catatonic.dk> writes:

> I want to reload everything. First I try to flush:
>
>     foreach (MyObject_LazySharedPointer P, myPool.values()):
>     {
>         P.unload();
>     }

I assume myPool is some map of object ids to LazySharedPointer<MyObject>.
Then, provided nobody else holds pointers to these objects, the above
should simply release all the objects in your pool. So you are not
really reloading in the sense of refreshing the state of existing
objects from the database. Rather, you are simply freeing the old
objects and loading new ones.

BTW, I don't see a good reason for using LazySharedPointer in the
pool. To me it looks like normal SharedPointer will work just as
well (and hopefully will minimize the confusion).

> Trouble with duplicated instances forced me to use sessions.

Yes, you have cycles (parent pointing to child and child pointing
to parent), so you need to use the session to be able to properly
load the whole thing.


> Now I cannot properly reload the tree, even though I call
> QLazySharedPointer::reload on all my instances:

What exactly doesn't work?


>         for (MyObject_Result::iterator I (result.begin()); I !=
> result.end(); ++I)
>         {
>             MyObject_LazySharedPointer P = I.load();
>             db->reload (P.data());

I don't see a point in calling reload() on an object that has just
been loaded, unless a "stale" instance was cached in the session.
But as far as I can see, this shouldn't happen in your case. To
make sure that's the case, you may want to limit the lifetime of
the session so that it is in effect only when you load the pool.
For example:

{
  session s;
  
  for (MyObject_Result::iterator I (result.begin()); ...)
  {
    ...
  }
}

If the objects are not shared among the trees, then you should
even be able to move the session inside the for-loop:
  
  for (MyObject_Result::iterator I (result.begin()); ...)
  {
    session s;
    ...
  }


> A slightly confusing setup, I admit.

No kidding ;-).


> Can database::reload be used to force a reload of an object that
> is already owned by a QLazySharedPointer?

Yes, provided QLazySharedPointer is loaded (i.e., it points to the
object instead of just containing the id), call to reload() will
reload its state from the database.

Boris



More information about the odb-users mailing list