Hi Marcin,

A few points adding to what Robert has already mentioned...

On Mar 27, 2008, at 4:33 PM, Marcin Skladaniec wrote:
"There are several object-relational mapping (ORM) java frameworks in existence, and in my opinion Cayenne (http://cayenne.apache.org/) is one of the best. Cayenne has clear and consistent API, and great, most vibrant community I met in the open source world. Cayenne has many features you one would expect ORM to have, but it is lacking one important feature which is present in competing projects like Hibernate: inheritance. I would like to propose a Summer of Code project bringing inheritance to Cayenne.

Cayenne has single table inheritance fully working. So it is not missing inheritance, just vertical and horizontal varieties of inheritance mapping.


At the moment Cayenne does support only some sort of flat inheritance (called 'derived entities' ), but it is already marked as deprecated and will be excluded from future versions.

It is already dropped from 3.0


I believe (re)adding this feature is going to highly improve Cayenne as ORM, I have already found myself missing it few times when working on various database designs.

This may require some discussion. IIRC there was a thread on that in the past, but I wouldn't call that inheritance, and for SoC I would recommend to concentrate on *object* inheritance, which requirements are well defined and well understood. BTW, here is a page that Ari created that outlines the 3 varieties:

http://cayenne.apache.org/doc/inheritance-overview.html


Example: If an application has an entity representing different payments each type of payment needs to be stored in separate table and will be mapped to a separate entity, ie. - CreditCardPayment[amount, bankedDate, ccNumber, ccExpiry, ...] <=> CreditCardPayment<amount, bankedDate, ccNumber, ccExpiry, ...> - ChequePayment[amount, dateBanked, chequeBank, ...] <=> ChequePayment<amount, dateBanked, chequeBank, ...> - CashPayment[amount, dateBanked, ...] <=> CashPayment<amount, dateBanked, ...> As can be seen some fields gets duplicated, and as there is no inheritance between the java classes the application ends up with plenty duplicate code. Also the relationships between the entities might get complicated, for example an Invoice would need to have separate relationship to each payment table.

Absolutely correct.


Flat inheritance

Let's call it "single table" to be consistent with the established terminology.

Using flat inheritance has only limited usage, and if used to extensively leads to tables with too many columns to be readable and understandable.

The explanation is correct, but "limited usage" is an overstatement. It is very useful and performs better than any other kind. So I guess we shouldn't try to make a case that vertical/horizontal is better than single table... It's just different, not better. All three have their uses.

Example: In the same situation as before there would be only one table defining all the fields : - Payment[amount, bankedDate, ccNumber, ccExpiry,..., chequeBank, ...] <=> CreditCardPayment<amount, bankedDate, ccNumber, ccExpiry, ...>, ChequePayment<amount, dateBanked, chequeBank, ...>, CashPayment<amount, dateBanked, ...> Modelling the relationships becomes much easier, but as each entity still is separate there is a high possibility of duplicate code.

Not true. There is a common superclass. Single table inheritance is a real inheritance in a Java sense... Consider it a mapping technique used to map a tree hierarchy of classes to a single table.


Horizontal inheritance can be considered a small improvement over the no inheritance model, keeping the duplication of the fields on the database and entity level, but allowing to gather some code together. I'm finding this approach a little confusing and counter- intuitive, but it certainly has a reason behind: it does avoid the slowness related with vertical inheritance.
Example:
- (no database table) <=> Payment<amount, bankedDate, ...> implements/extends CreditCardPayment, ChequePayment, CashPayment - CreditCardPayment[ccNumber, ccExpiry, ...] <=> CreditCardPayment<ccNumber, ccExpiry, ...>
- ChequePayment[chequeBank, ...] <=> ChequePayment<chequeBank, ...>
- CashPayment[...]  <=> CashPayment<...>


Vertical inheritance escapes the problems of flat inheritance by storing data relevant to an entity in a dedicated table. Resulting database schema is cleaner and easier to maintain when adding new entities and tables. There is a cost linked with this type of inheritance: the database transaction speeds are lower, since each fetching query must use a join and storing data has to be executed against each table. Example: Again the same situation as in previous cases. In vertical inheritance there is a common table and common entity class finally creating a room for the code common to all Payments: - Payment[amount, bankedDate, ...] <=> Payment<amount, bankedDate, ...> - CreditCardPayment[ccNumber, ccExpiry, ...] <=> CreditCardPayment<ccNumber, ccExpiry, ...> extends Payment - ChequePayment[chequeBank, ...] <=> ChequePayment<chequeBank, ...> extends Payment
- CashPayment[...]  <=> CashPayment<...>  extends Payment


My Google Summer of Code is going to bring the inheritance to Cayenne. Certainly I would like to implement the vertical inheritance, albeit it might have performance impact, it also seems to be the most advanced model. If the time will allow I'll put my effort to also implement either flat or horizontal inheritance, consulting the Cayenne community to find which one is more anticipated. "


Again, I disagree that single table is inferior... There are three classic ways to map OO inheritance hierarchy to the relational model. We have one, we need one or two more to give users more flexibility.

Finally, please don't take my comments as a negative reaction. I am very happy that we have this proposal and looking forward to working with you on implementing them.

Cheers,
Andrus

Reply via email to