[odb-users] Problem with inheritance and composite value

Aldo Laiseca alaiseca at gmail.com
Thu Jan 11 18:30:53 EST 2024


Hi, I would appreciate some help to overcome a problem with this scenario: 

I have three clases, say A,B,C, mapping to three different tables. All the tables have in common a set of columns which I consider appropriate to be grouped into a composite value, so I created a class, say CV, to represent that composite value, like this: 

/* CV.h */

#include <odb/core.hxx>
#include <string>
#include <memory>
#include <AnotherEntity.h>

#pragma db value
class CV {
private:
    #pragma db get(getPropertyA) set(setPropertyA)
    #pragma db column(“prop_a") not_null
    std::string propA;

    #pragma db get(getPropertyB) set(setPropertyB)
    #pragma db column(“prop_b") not_null
    std::string propB;

    #pragma db get(getAnotherEntity) set(setAnotherEntity)
    #pragma db column("id_another_entity") not_null
    std::shared_ptr<AnotherEntity> anotherEntity;

    …
public:
    CV() = default;
    virtual ~CV() = default;

    std::string getPropertyA() const;
    void setPropertyA(const std::string& propA);

    std::string getPropertyB() const;
    void setPropertyB(const std::string& propB);

    std::shared_ptr<AnotherEntity> getAnotherEntity() const;
    void setAnotherEntity(std::shared_ptr<AnotherEntity> anotherEntity);
    ...
};

Now, since three tables have the same group of columns, instead of repeating the composite value as property and its getters and setters methods in each class A, B and C, I thought I was a better idea to have a common base abstract class doing so, like this: 

/* BaseClass.h */

#include <odb/core.hxx>
#include “CV.h"

#pragma db object abstract
class BaseClass {
protected:
    #pragma db get(getCV) set(setCV)
    CV cv;

    CV() = default;
    virtual ~CV() = default;

public:
    CV getCV() const;
    void setCV(const CV& cv);
};

And class A, for instance, would look like this (similar for B and C):

/* A.h */

#pragma db object table(“table_A")
class A : public BaseClass {
private:
   /* Declare all the necessary properties except those already included in CV */
    
};

My odb compiler script looks like this:

odb -I /usr/local/include -d pgsql --std c++17 BaseClass.h
odb -I /usr/local/include -d pgsql --std c++17 InfoDomicilio.h
odb -I /usr/local/include -d pgsql --generate-query --std c++17 A.h

No problems so far; files -odb.hxx and orb-ixx being generated ok for all the above lines.

However, at the moment I try to write a query for clase A like this: 

#include "A.h"
#include "A-odb.hxx"

typedef odb::query<A> query;

std::shared_ptr<A> MyDAO::searchByPropX(const std::string &ref)
{
    return db->query_one<A>(query::propX == query::_ref(ref));
}

My compiler (clang Mac OS Intel with BigSur 11.7) complains:

A-odb.hxx:483:5: error: implicit instantiation of undefined template 'odb::query_columns<BaseClass, odb::id_pgsql, odb::access::object_traits_impl< ::A, id_pgsql>>'
    query_columns< ::BaseClass, id_pgsql, A >,

/usr/local/include/odb/pgsql/query.hxx:2050:25: note: in instantiation of template class 'odb::query_columns<A, odb::id_pgsql, odb::access::object_traits_impl< ::A, id_pgsql>>' requested here
                 public query_selector<T, id_pgsql>::columns_type

/usr/local/include/odb/pgsql/query.hxx:2120:45: note: in instantiation of template class 'odb::pgsql::query<A>' requested here
  class query<T, pgsql::query_base>: public pgsql::query<T>
                                            ^
../MyDAO.cpp:9:38: note: in instantiation of template class 'odb::query<A, odb::pgsql::query_base>' requested here
    return db->query_one<A>(query::propX == query::_ref(ref));
                                     ^
/usr/local/include/odb/query.hxx:30:10: note: template is declared here
  struct query_columns;
         ^
In file included from ../MyDAO.cpp:3:
../A-odb.hxx:484:5: error: implicit instantiation of undefined template 'odb::query_columns<BaseClass, odb::id_pgsql, odb::access::object_traits_impl< ::A, id_pgsql>>'
    query_columns< ::BaseClass, id_pgsql, A >
    ^
/usr/local/include/odb/query.hxx:30:10: note: template is declared here
  struct query_columns;
         ^
1 warning generated.
../MyDAO.cpp:9:62: error: no member named '_ref' in 'odb::query<A, odb::pgsql::query_base>'
    return db->query_one<A>(query::propX == query::_ref(ref));


Could you please advise on this? 

Any help is highly appreciated. Thanks!!!






More information about the odb-users mailing list