From d001ec3018787138c2db6c5f6949a00807582774 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov odb::transaction
class and are discussed
in Section 3.4, "Transactions".
The next three exceptions (already_in_session
,
- not_in_session
, and
- const_object
) are thrown by the
- odb::session
class and are discussed
- in Chapter 9, "Session".
The next two exceptions (already_in_session
, and
+ not_in_session
) are thrown by the odb::session
+ class and are discussed in Chapter 9, "Session".
The recoverable
exception serves as a common base
for all the recoverable exceptions, which are: connection_lost
,
@@ -6051,26 +6043,43 @@ t.commit ();
a pre-allocated instance, the object is only cached if its object
pointer is a raw pointer.
Finally, the session caches both constant and unrestricted objects,
- depending on whether a constant reference or constant pointer was
- passed to the database::persist()
function (in contrast,
- when loaded, objects are always created and cached as unrestricted).
- If we try to load an object as unrestricted that was previously
- persisted and cached as constant, the odb::const_object
- exception is thrown. The following transaction shows the
- situation where this would happen:
Also note that when we persist an object as a constant reference
+ or constant pointer, the session caches such an object as
+ unrestricted (non-const
). This can lead to undefined
+ behavior if the object being persisted was actually created as
+ const
and is later found in the session cache and
+ used as non-const
. As a result, when using sessions,
+ it is recommended that all persistent objects are created as
+ non-const
instances. The following code fragment
+ illustrates this point:
-shared_ptr<const person> p (new person ("John", "Doe")); +void save (database& db, shared_ptr<const person> p) +{ + transaction t (db.begin ()); + db.persist (p); // Persisted as const pointer. + t.commit (); +} session s; -transaction t (db.begin ()); -unsigned long id (db.persist (p)); -shared_ptr<const person> p1 (db.load<const person> (id)); // Ok. -shared_ptr<person> p2 (db.load<person> (id)); // Exception. +shared_ptr<const person> p1 (new const person ("John", "Doe")); +unsigned long id1 (save (db, p1)); // p1 is cached in s as non-const. -t.commit (); +{ + transaction t (db.begin ()); + shared_ptr<person> p (db.load<person> (id1)); // p == p1 + p->age (30); // Undefined behavior since p1 was created const. +} + +shared_ptr<const person> p2 (new person ("Jane", "Doe")); +unsigned long id2 (save (db, p2)); // p2 is cached in s as non-const. + +{ + transaction t (db.begin ()); + shared_ptr<person> p (db.load<person> (id2)); // p == p2 + p->age (30); // Ok, since p2 was not created const. +}-- cgit v1.1