[odb-users] Composite object id with a to-many relationship
Boris Kolpackov
boris at codesynthesis.com
Fri Nov 15 03:49:07 EST 2013
Hi Romain,
Romain Gros <grosr.romain at gmail.com> writes:
> The fact is that I cannot specify, in the inverse pragma member, something
> like that: inverse(_idobjectspecification._idinstance), which would be
> perfect for me.
Conceptually, what you are trying to do is use a foreign key as part
of the primary key, or, in ODB terms, use an object pointer as part
of an object id:
#pragma db value
class ObjectSpecificationId
{
private:
std::shared_ptr<ObjectInstance> _idinstance;
int _idspecification;
};
ODB currently does not support this and I am not sure we will support
it in the future because of the extra complexity involved.
> To simulate the fact that we can access the
> ObjectSpecificationId::_idinstance, I use a reference to the ObjectInstance
> in the ObjectSpecification (as shown above).
> The thing work well for the load, but with that, I cannot insert new
> ObjectSpecification, because the persist_statement generated defines two
> times the idinstance and cause an MySQL error:
> "INSERT INTO `ObjectSpecification` "
> "(`idinstance`, "
> "`idspecification`, "
> "`value`, "
> "`idinstance`) "
> "VALUES "
> "(?, ?, ?, ?)";
Right. You basically mapped two data members to the same column, which
won't work.
> Do you know a good way to do that?
I think the best way is to keep it simple and just duplicate the
ObjectInstance id in both the ObjectSpecification id and the
pointer. You will incur a small overhead by storing the same
value in two columns, but other than that, things will be nice
and simple.
> Also, a solution that I didn't try yet is the use of the post_load
> callback, but if I do that, I'm afraid that I won't be able to use
> lazy_ptr, right ?
No, this won't work because of the inverse() pragma in ObjectInstance.
Also, another thing that you may consider is making ObjectSpecification
a value, rather than an object. If you look at the table structure you
are trying to achieve, it is pretty much the same as what you get with a
container:
#pragma db value
class ObjectSpecification
{
int _value;
};
#pragma db object
class ObjectInstance
{
typedef std::vector<ObjectSpecification> ObjectSpecificationType;
ObjectSpecificationType _specifications;
};
Here the container's index becomes _idspecification. If you want to
make it lazy-loaded, you can put it in a section (ODB 2.3.0).
Boris
More information about the odb-users
mailing list