Re: Inheritance Mapping

Armin Waibel <[email protected]>
Newsgroups gmane.comp.jakarta.ojb.user
Message-ID <[email protected]>
Adam Brons wrote:
> Thanks for the response Armin.  What you mentioned may be right, but 
> either case isn't what I'm wanting.
> 
> The scenario that I'm trying to solve is this:
> 
>         1 database table Employee and Manager
>         The MANAGER_EMPLOYEE_MAP is a mapping table for an additional 
> collection
>                 that the Manager class has (aka a list of employee's 
> s/he's responsible for).  This just 
>                 points BACK to the employee table.
> 
>> You use a discriminator column to identify the real class (used in 
>> "table per class"), but in your posted database table script it seems 
>> you expect a "table per subclass" mapping.
> Yes I added the ojbConcreteClass column to identify the real class, 
> because what I want to happen is that when loading the Company class 
> collection (as defined in the repository configuration) it will use the 
> objConcreteClass specified class.  So the Company class would contain a 
> collection of Employee and Manager classes.
>

Which version of OJB do you use?
I modify/extend a test of OJB's test-suite to reproduce your problem - 
without success, the test pass (I use latest version from SVN, 
OJB_1_0_RELEASE branch).

Think the test is very similar to your problem (maybe more complicated 
then your scenario):

The mapping
-----------

<class-descriptor
    	  class="org.apache.ojb.broker.ProductGroup"
    	  proxy="org.apache.ojb.broker.ProductGroupProxy"
    	  table="Kategorien"
    >
...
<collection-descriptor
          name="allArticlesInGroup"
          element-class-ref="org.apache.ojb.broker.AbstractArticle"
          auto-retrieve="true"
          auto-update="true"
          auto-delete="false"
       >
          <orderby name="articleId" sort="DESC"/>

          <inverse-foreignkey field-ref="productGroupId"/>
       </collection-descriptor>

....
</class-descriptor>


<class-descriptor
    	  class="org.apache.ojb.broker.Article"
    	  proxy="dynamic"
    	  table="Artikel"
    >
       <extent-class class-ref="org.apache.ojb.broker.BookArticle" />
       <extent-class class-ref="org.apache.ojb.broker.AbstractCdArticle" />
       <field-descriptor
          name="articleId"
          column="Artikel_Nr"
          jdbc-type="INTEGER"
          primarykey="true"
          autoincrement="true"
       />
....
</class-descriptor>


<class-descriptor
	  class="org.apache.ojb.broker.BookArticle"
	  table="BOOKS"
    >
       <field-descriptor
          name="articleId"
          column="Artikel_Nr"
          jdbc-type="INTEGER"
          primarykey="true"
          autoincrement="true"
       />
....
</class-descriptor>


<class-descriptor class="org.apache.ojb.broker.AbstractCdArticle">
       <extent-class class-ref="org.apache.ojb.broker.CdArticle" />
</class-descriptor>


<class-descriptor
    	  class="org.apache.ojb.broker.CdArticle"
    	  table="CDS"
    >
       <field-descriptor
          name="articleId"
          column="Artikel_Nr"
          jdbc-type="INTEGER"
          primarykey="true"
          autoincrement="true"
       />

....
</class-descriptor>


The test
--------

public void testCollectionRetrieval() throws Exception
{
...
ProductGroup group=(ProductGroup) broker.getObjectByQuery(....

     // expect 7 Article, 2 Books, 3 Cds
     assertEquals("check size",group.getAllArticles().size(),12);
     List articles = group.getAllArticles();
     int countArticle = 0;
     int countBook = 0;
     int countCD = 0;
     for(int i = 0; i < articles.size(); i++)
     {
         Object o =  articles.get(i);
         //System.out.println("Result: " + o);
         if(o instanceof Article)
         {
             countArticle++;
         }
         if(o instanceof BookArticle)
         {
             countBook++;
         }
         if(o instanceof CdArticle)
         {
             countCD++;
         }
     }
     // all objects are instance of Article
     assertEquals(12, countArticle);
     assertEquals(2, countBook);
     assertEquals(3, countCD);
}

regards,
Armin


> 
> 
> 
> 
> Armin Waibel <[email protected]> 
> 03/06/07 02:29 PM
> Please respond to
> "OJB Users List" <[email protected]>
> 
> 
> To
> OJB Users List <[email protected]>
> cc
> 
> Subject
> Re: Inheritance Mapping
> 
> 
> 
> 
> 
> I think you mixed up two different inheritance strategies.
> 
> table per class
> file:///E:/dev/db-ojb-1b/ojb/doc/docu/guides/advanced-technique.html#Mapping+Each+Class+of+a+Hierarchy+to+a+Distinct+Table+%28table+per+class%29
> 
> 
> table per subclass
> file:///E:/dev/db-ojb-1b/ojb/doc/docu/guides/advanced-technique.html#Mapping+Each+Subclass+to+a+Distinct+Table+%28table+per+subclass%29
> 
> 
> You use a discriminator column to identify the real class (used in 
> "table per class"), but in your posted database table script it seems 
> you expect a "table per subclass" mapping.
> Could this be the issue?
> 
> regards,
> Armin
> 
> 
>> The following is an EXAMPLE of what I'm trying to do.
>>
>> Classes --- Based on documentation examples:
>> ==================================
>> public class Company {
>>         private Integer id;
>>         private Collection<Employee> employees;
>>         private String name;
>>
>>         public Company() { }
>>
>>         public Integer getId() {
>>                 return id;
>>         }
>>         public void setId(Integer id) {
>>                 this.id = id;
>>         }
>>         public Collection<Employee> getEmployees() {
>>                 if (employees == null) 
>>                         employees = new ArrayList();
>>
>>                 return employees;
>>         }
>>         public void setEmployees(Collection<Employee> employees) {
>>                 this.employees = employees;
>>         }
>>         public String getName() {
>>                 return name;
>>         }
>>         public void setName(String name) {
>>                 this.name = name;
>>         }
>> }
>>
>> public class Employee {
>>         protected Integer id;
>>         protected Integer companyId;
>>         protected String name;
>>         protected String ojbConcreteClass;
>>
>>         public Employee() { this.ojbConcreteClass = 
>> this.getClass().getName(); }
>>
>>         public Integer getId() {
>>                 return id;
>>         }
>>         public void setId(Integer id) {
>>                 this.id = id;
>>         }
>>         public Integer getCompanyId() {
>>                 return companyId;
>>         }
>>         public void setCompanyId(Integer companyId) {
>>                 this.companyId = companyId;
>>         }
>>         public String getName() {
>>                 return name;
>>         }
>>         public void setName(String name) {
>>                 this.name = name;
>>         }
>>         public String getOjbConcreteClass() {
>>                 return ojbConcreteClass;
>>         }
>>         public void setOjbConcreteClass(String ojbConcreteClass) {
>>                 this.ojbConcreteClass = ojbConcreteClass;
>>         }
>> }
>>
>> public class Manager extends Employee {
>>         private Collection<Employee> employees;
>>
>>         public Manager() { super(); }
>>
>>         public Collection<Employee> getEmployees() {
>>                 if (employees == null) 
>>                         employees = new ArrayList();
>>
>>                 return employees;
>>         }
>>         public void setEmployees(Collection<Employee> employees) {
>>                 this.employees = employees;
>>         }
>> }
>>
>> Database(DB2) tables:
>> ================
>> CREATE TABLE company (
>>   company_id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1 
> 
>> INCREMENT BY 1),
>>   name varchar(255) NOT NULL,
>> --
>>   PRIMARY KEY (company_id)
>> );
>>
>> CREATE TABLE employee (
>>   employee_id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 
> 1 
>> INCREMENT BY 1),
>>   name varchar(255) NOT NULL,
>>   company_id_FK INTEGER NOT NULL,
>>   class_name varchar(255) NOT NULL,
>> --
>>   PRIMARY KEY (employee_id), 
>>   FOREIGN KEY (company_id_FK) REFERENCES company (company_id)
>> );
>>
>> CREATE TABLE manager_employee_map (
>>   manager_id_FK INTEGER NOT NULL,
>>   employee_id_FK INTEGER NOT NULL,
>> --
>>   FOREIGN KEY (manager_id_FK) REFERENCES employee (employee_id),
>>   FOREIGN KEY (employee_id_FK) REFERENCES employee (employee_id)
>> );
>>
>> Repository mapping:
>> ===============
>> <class-descriptor class="Company" table="COMPANY">
>>         <field-descriptor name="id" column="COMPANY_ID" 
>> jdbc-type="INTEGER"
>>           primarykey="true" autoincrement="true" access="readonly"/>
>>         <field-descriptor name="name" column="NAME" jdbc-type="VARCHAR" 
> />
>>         <collection-descriptor name="employees"
>>         element-class-ref="Employee"
>>         auto-delete="true" auto-update="true" auto-insert="true" 
>> auto-retrieve="true">
>>         <inverse-foreignkey field-ref="CompanyId"/>
>>     </collection-descriptor>
>> </class-descriptor>
>>
>> <class-descriptor class="Employee" table="employee"> 
>>         <extent-class class-ref="Manager"/>
>>         <field-descriptor name="id" column="EMPLOYEE_ID" 
>> jdbc-type="INTEGER"
>>          primarykey="true" autoincrement="true" access="readonly"/>
>>         <field-descriptor name="name" column="NAME" jdbc-type="VARCHAR" 
> />
>>         <field-descriptor name="companyId" column="COMPANY_ID_FK" 
>> jdbc-type="INTEGER"/>
>>         <field-descriptor name="ojbConcreteClass" column="CLASS_NAME" 
>> jdbc-type="VARCHAR" />
>> </class-descriptor>
>>
>> <class-descriptor class="Manager" table="employee"> 
>>         <field-descriptor name="id" column="EMPLOYEE_ID" 
>> jdbc-type="INTEGER"
>>          primarykey="true" autoincrement="true" access="readonly"/>
>>         <field-descriptor name="name" column="NAME" jdbc-type="VARCHAR" 
> />
>>         <field-descriptor name="companyId" column="COMPANY_ID_FK" 
>> jdbc-type="INTEGER"/>
>>         <field-descriptor name="ojbConcreteClass" column="CLASS_NAME" 
>> jdbc-type="VARCHAR" />
>>
>>         <collection-descriptor name="employees"
>>          element-class-ref="Employee"
>>          auto-retrieve="true" auto-update="true" auto-delete="true"
>>          indirection-table="MANAGER_EMPLOYEE_MAP">
>>                 <fk-pointing-to-this-class column="MANAGER_ID_FK"/>
>>                 <fk-pointing-to-element-class column="EMPLOYEE_ID_FK"/>
>>         </collection-descriptor> 
>> </class-descriptor>
>>
>>
>> Adam Brons
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> 
> 
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.