2

Consider this highly simplified sample of relational data (each table may be involved in one-to-many and many-to-many relationships not shown here):

people +-------+------+--------+ | name | born | gender | +-------+------+--------+ | Alice | 1980 | F | | Bob | 1975 | M | | Carl | 1994 | M | | Dot | 1942 | F | +-------+------+--------+ workers students +-------+---------+-------+ +-------+-------------+-------+ | name | company | since | | name | institution | since | +-------+---------+-------+ +-------+-------------+-------+ | Alice | Soylent | 2003 | | Alice | Western | 2001 | | Bob | HAL | 1999 | | Carl | Eastern | 2012 | +-------+---------+-------+ +-------+-------------+-------+ 

Some people are workers (Bob), some are students (Carl), some are neither (Dot).
Some are both (Alice).

Mapping to OOP, it would be straightforward to have three classes, like:

class Worker extends Person class Student extends Person 

But that's ok as long as the specialization is disjoint: object alice can't be instance of Worker and Student at the same time. If you get a list of Person objects, you cannot cast the same element to both subclasses.

First of all, is there any specific name for this (likely common) impedance mismatch case?

Next, suppose you can't remodel the schema. I may have my own way to workaround with OOP, but I'm mainly interested in yours. Is there some sort of best-practice guideline?
This example has only two ISA relations, but my impression is, the more non-disjoint sub-entities, the more OOP gets uncomfortable.

2 Answers 2

3

One way to do this would be to model this in the application using composition:

//maps to the table PEOPLE class Person { String name; Date birthdate; GenderEnum gender; Worker workerAttributes; Student studentAttributes; } //maps to the table WORKERS class Worker { String name; String company; Date since; } //maps to the table STUDENTS class Student { String name; String institution; Date since; } 

Each Person object contains an object containing Worker information and Student information. When you populate these objects, you would have to ensure that you've joined to the correct Person.

1
  • Clean. This is close to what I have in mind... Commented Nov 14, 2014 at 16:03
1

I don't know how it's modeled in your application, but in the real world, people cannot only be both student and worker, they can be workes at different companies at the same time. Now looking closer at the tables shows that they look like N:N join tables, don't they?

So what I would do is rename Student to Enrollment and Worker to Contract. Person now has two N:N relations, one with Institution, and one with Company. In terms of OOP:

class Person { Collection<Enrollment> enrollments; Collection<Contract> employmentContracts; } 
1
  • Ah! You got me Yogu :) You're right, in my example the workers and students tables really look like intermediate tables for many-to-many relations (someone would call them pivot tables) but it was not intentional. Thanks for pointing it out (upvote!). My fault, I should have pointed up that the name column in all the tables must be considered a unique key. I also realize that the example is somewhat oversimplified, so I'm going to edit the question soon and try to improve it. Commented Nov 15, 2014 at 10:52

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.