[odb-users] Re: Self persisting objects?

Boris Kolpackov boris at codesynthesis.com
Thu Aug 30 09:37:42 EDT 2012


Hi Oded,

Oded Arbel <oded at geek.co.il> writes:

> libodb-2.0.1\odb\database.ixx(49): error C2440: 'initializing' :
> cannot convert from 'model::Employee *' to 'const object_pointer &'

If you look at that line, there is a helpful comment preceding it
that reads:

    // The passed pointer should be the same or implicit-convertible
    // to the object pointer. This way we make sure the object pointer
    // does not assume ownership of the passed object.
    //

So what most likely happens is you are using a smart pointer (e.g.,
shared_ptr) as an object pointer. If that's the case then you may
want to use the shared_from_this (or similar) machinery to get the
shared pointer from this.

Also note that the distinction between persisting via object
pointer and via reference only comes into play if you are using
sessions (if object pointer is not the raw pointer then by-
reference persist() won't add the object to the session). So if
you are not planning to use sessions, then you can instead
replace:

s_db->persist(this);

With:

s_db->persist(*this);


> The implementation of Employee::persist() could be pretty trivial
> (assuming someone knows how to initialize a database connection. I'm
> going to leave that as an exercise to the user and assume an already
> inited static field):
>
> void Employee::persist() {
> 	odb::transaction t(s_db->begin());
> 	s_db->persist(this);
> 	t.commit();
> }

Just a side note: a better design might be to leave it to the caller
of Employee::persist() to create the transaction. This way the caller
will be able to persist several objects at once:

Employee e1, e2;

odb::transaction t (db->begin ());
e1.persist ();
e2.persist ();
t.commit ();

The added benefit of this approach is that you can get the database
from the current transaction without having to store it in a static
field or similar:

void Employee::persist() {
  odb::transaction& t (odb::transaction::current ());
  odb::database& db (t.database ());
  db.persist (*this);
}

Boris



More information about the odb-users mailing list