[odb-users] Composite object id with a to-many relationship

Romain Gros grosr.romain at gmail.com
Fri Nov 15 22:11:49 EST 2013


Hi Boris,

Thank you for your answer, it works perfectly !

Romain


2013/11/15 Boris Kolpackov <boris at codesynthesis.com>

> 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