[odb-users] Re: how to properly use odb::nullable

Boris Kolpackov boris at codesynthesis.com
Sat Jun 2 14:22:05 EDT 2012


Hi Huy,

In the future please send technical questions like these to the
odb-users mailing list (which I've CC'ed) instead of to me directly,
as discussed in the posting guidelines:

http://www.codesynthesis.com/support/posting-guidelines.xhtml

Huy Nguyen <hmnd42009 at gmail.com> writes:

> I'm trying use odb::nullable<int> to create a NULL value (this value
> is also the referential foreign key, this is key *controller_id*)
> 
> My *constructor *is defined:
> 
>  sources (int id, int controller_id)
>   : id_(id) , controller_id_(controller_id){}
> 
> In my private member I have:
> 
>   #pragma db id auto
>   int id_ ;
>   odb::nullable<int> controller_id_;
> 
> I'm creating a transient object with:
>   sources sourcesA (125,NULL);
> 
> But the persist failed because of the foreign key check even though the
> foreign key is set to allow NULL value.

The int type doesn't have a notion of the special NULL value. The way
you create your object is essentially equivalent to this:

sources sourcesA (125, 0);

Which will initialize the controller_id_ member to 0 int value, not
the NULL special value (that's also the reason why we have to wrap
int with odb::nullable).

One way to fix your constructor is to pass a pointer to int, which
will give us a special value (NULL pointer):

sources (int id, const int* controller_id)
  : id_ (id)
{
  if (controller_id != 0)
    controller_id_ = *controller_id;
}

The problem with this constructor is that it is inconvenient to use
if you want to pass a non-NULL value. Now we have to write:

int cid (123)
sources sourcesA (125, &cid);

Instead of just:

sources sourcesA (125, 123);

So instead of passing a pointer you may want to add another overload
of the constructor that will be used to create objects with controller_id
set to NULL:

sources (int id, int controller_id)
  : id_ (id), controller_id_ (controller_id) {}

sources (int id)
  : id_ (id) {}

Now we can write:

sources sourcesA (125, 123); // controller_id is 123
sources sourcesB (126);      // controller_id is NULL

Yet another option is to use odb::nullable<int> instead of int as the
controller_id parameter.

For more information on the odb::nullable interface, refer to Section
7.3, "Pointers and NULL Value Semantics" in the ODB manual:

http://www.codesynthesis.com/products/odb/doc/manual.xhtml#7.3

Boris



More information about the odb-users mailing list