Skip to content

A Wicket API for Google Charts

12
Dec
2007

Google made the headlines last week with their announcement of a brand new API for graphical display of data, supporting several different display types (line, bar, pie, etc).  The API (such as it is) works by taking different parameters as part of a URL and then generating a PNG chart based on the data.  For example:

http://chart.apis.google.com/chart?cht=p3&chd=s:hW&chs=250x100&chl=Hello|World

Great, so now you all know that I can read publicly available websites.  What’s cool here is I can tweak the graph however I please, just by messing with the URL:

http://chart.apis.google.com/chart?cht=p3&chd=s:hWj&chs=250x100&chl=Hello|Chicago|London

Pretty magical!  But aside from playing with different ways to represent useless information in 3D, it’s hard to imagine actually using it in one of your own web applications.  Oh sure, maybe you’ll employ it to generate the odd plot for your blog now and again, but for your really solid business needs, you’re going to stick with something which has a slightly more developer-friendly API.

I was pondering different excuses I could use to convince myself to try this new tool somewhere when it struck me: what about Wicket?  Wicket’s entire structure is based around extreme component extensibility.  The framework is designed to allow developers to create their own third-party components and use them as easily as those in the core Wicket API.  In fact, to even use Wicket at all requires the creation of custom components, implicitly or otherwise.

So the idea is to create a nice, object-oriented Chart component backed by Google Charts and usable in any Wicket project.  The API should follow the conventions laid down by the Wicket API itself, and be relatively easy to understand as well.  :-)   Obviously the Google Charts URL “API” follows a very strict set of constraints, thus it should be possible to render some sort of object-oriented MVC representation of a chart down into the required URL.  Thanks to Wicket componentization, it should even be possible to seamlessly utilize the component within a standard page.

I took some time today, and managed to prototype a fully-functional version of just such an API.  Cleverly enough, I’m calling it “wicket-googlecharts”.  Thanks to the inherent complexities of charting and the difficulties of intuitively mapping the concepts into an object-oriented hierarchy, the API is still a bit odd.  However, I’m fairly confident that it’s easier than doing the URLs by hand:

IChartData data = new AbstractChartData() {
    public double[][] getData() {
        return new double[][] {{34, 22}};
    }
};
 
ChartProvider provider = new ChartProvider(new Dimension(250, 100), 
        ChartType.PIE_3D, data);
provider.setPieLabels(new String[] {"Hello", "World"});
 
add(new Chart("helloWorld", provider));
 
data = new AbstractChartData() {
    public double[][] getData() {
        return new double[][] {{34, 30, 38, 38, 41, 22, 41, 44, 38, 29}};
    }
};
 
provider = new ChartProvider(new Dimension(200, 125), ChartType.LINE, data);
 
ChartAxis axis = new ChartAxis(ChartAxisType.BOTTOM);
axis.setLabels(new String[] {"Mar", "Apr", "May", "June", "July"});
provider.addAxis(axis);
 
axis = new ChartAxis(ChartAxisType.LEFT);
axis.setLabels(new String[] {null, "50 Kb"});
provider.addAxis(axis);
 
add(new Chart("lineHelloWorld", provider));

And the HTML:

<html xmlns:wicket="http://wicket.apache.org">
    <body>
        <h2>Hello World</h2>
 
        <img wicket:id="helloWorld"/>
 
        <h2>Line Hello World</h2>
 
        <img wicket:id="lineHelloWorld"/>
    </body>
</html>

The resulting charts look like this:

    

I know, pretty much the same charts that we have above. Not terribly impressive.  What should be impressive is that all of this was configured using Java.  I didn’t have to understand the Google Charts URL structure.  I didn’t have to even think about what goes on behind the scenes.  In fact, as far as the API is concerned, there could be an entirely different chart generating engine working under the surface, the developer doesn’t care.

Architecture

The real component of interest here is the Chart component that we add to the enclosing container at two different points (one instance for each chart).  This is where the actual work goes on, transforming the object hierarchy into a properly formatted URL. 

The class itself is surprisingly simple.  Basically it’s just a bunch of logic that runs through the hierarchy represented in IChartProvider (and yes, I am following the Wicket convention and using interfaces everywhere).  Chart contains almost all of the semantics of the Google Charts API itself, providing a nice separation of concerns from a maintainability standpoint.  This way, if Google changes the API down the road (and you know they will), it’s a simple matter of tweaking the Chart class, allowing the rest of the hierarchy to remain untouched.

As far as Wicket is concerned, here’s the only interesting bit in the entire API:

@Override
protected void onComponentTag(ComponentTag tag) {
    checkComponentTag(tag, "img");
    super.onComponentTag(tag);
 
    tag.put("src", constructURL());
}

Devilishly clever, I know.  See how incredibly easy it is to write your own Wicket component?  Practically speaking, there’s almost nothing going on here.  All we do is listen for the onComponentTag event, verify that we are indeed working with an <img/> tag, modify the src attribute to some generated URL and we’re home free!  I really hate to go on and on about this, but the Wicket devs really deserve their props for making a very slick and extensible API.  Anyway, back to the charts mechanism…

That’s really about the only earth-shattering bit of code in the entire chart API.  constructURL just has a set of all of the attributes in which Google Charts is interested.  It blindly runs through these attributes, checking corresponding values in the IChartProvider instance.  If something is non-null, it’s run through a basic rendering algorithm (dependant on what attribute it is) and a properly formatted character sequence is spit out the other end.  Baby stuff.

More API

One thing that’s worth drawing attention to is that I tried to stick with Java-conventional values within the chart model rather than the more normal HTML values.  For example, setting the first two graph colors might look something like this:

provider.setColors(new Color[] {Color.RED, new Color(255, 0, 255, 127});

Notice the extra integer value in the second color?  Because the API is using proper java.awt.Color instances, we can specify colors not just in RGB, but in full ARGB (the ‘A’ stands for “alpha”), allowing transparency.  Alex Blewitt has an example of dubious usefulness which shows how this can be applied.

Of course, the full API is far too extensive to cover in a non-trivial blog post (much less a single night’s hard coding).  However, I did whip up a demo page that I’ve been using to test the framework.  It’s not hosted live right now, but I did upload the fully-rendered HTML.  Sources for this particular page are also available (java, html).

More importantly, I took the time to pilfer a build script from another project of mine and actually build a proper distributable for the library.  Both tarball and zip archive are available.  Go nuts!

Oh, one more thing…  I assume I don’t have to define the words “untested”, “prototype” and “danger-will-robinson”.  Just remember I warned you if your server inexplicably turns into a piece of fairy cake.

Update: The project has been released as a wicket-stuff subproject. You can get the source via SVN at this URL: https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicket-googlecharts

Polymorphic Relational Types in ActiveObjects

11
Dec
2007

Remember when I said that ActiveObjects would always attempt to take the simplest approach to any problem, even when it meant eschewing some more esoteric features?  Well, this is probably a bit of an exception.  Polymorphic types are most certainly not simple (at least, not from an ORM design standpoint) and I had to do a bit of hackery under the surface to make them work.  However, given the usefulness of this feature, I think that it was probably worthwhile.

Simply put, a polymorphic relational type is a table which has a relation with one or more other tables based on the value of a non-constrained field.  Got that?

Maybe a diagram would be helpful…

image

We’ve all seen this pattern at some time or other.  Rather than having insurancePolicies contain n mapping fields (e.g. “employeeID” and “managerID”), we make the mapping polymorphic and provide an ancillary type field which specifies which table is actually mapped.  This simplifies queries, not to mention making things far more extensible.  For example, if we wanted to add a janitors table here, we wouldn’t need to change insurancePolicies at all to allow mapping.  Rather, we just add the table and define (in our documentation) another type value which specifies janitors as opposed to employees as the mapped table.

So the concept itself is fairly straightforward.  The difficulties come when you try to map this into ORM-land.  At first glance, it seems like it should be a cakewalk.  Right away we can see some inline inheritance shared between employees and managers, so maybe our entities will look like this:

public interface Person extends Entity {
    public String getFirstName();
    public void setFirstName(String firstName);
 
    public String getLastName();
    public void setLastName(String lastName);
 
    @OneToMany
    public InsurancePolicy[] getPolicies();
}
 
public interface Employee extends Person {
    public int getHourlyWage();
    public void setHourlyWage(int wage);
}
 
public interface Manager extends Person {
    public long getSalary();
    public void setSalary(long salary);
}
 
public interface InsurancePolicy extends Entity {
    public int getValue();
    public void setValue(int value);
 
    public Person getPerson();
    public void setPerson(Person person);
}

As with any other form of table inheritance in ActiveObjects, the supertype doesn’t correspond to a table.  There’s no multi-JOIN mapping going on.  The difference is that now we’re not only inheriting fields from the supertype, but the inheritance also allows other entities to treat the type polymorphically on the supertype.  We can assume that the personType field is auto-generated by the ORM during the migration.  Seems reasonable enough.

Unfortunately, as it stands right now, ActiveObjects will blissfully recurse into the InsurancePolicy entity, see the getPerson method and precede to generate a table for Person, rather than ignoring Person in favor of its subtypes.  This is because AO has no way of knowing that Person even has subtypes.  Java doesn’t provide a convenient way of getting derived interfaces or anything so nice.  So as far as the migration process is concerned, Person is a totally valid entity which requires a peered table.

The solution here is fairly simple, just tack on an annotation to the Person type to indicate to the schema generator that any relations on the type are to be polymorphic.  I vacillated for a while between @Abstract and @Polymorphic, eventually choosing the latter.  However, if you have any strong preferences either way, let me know!

The new Person declaration looks something like this:

@Polymorphic
public interface Person extends Entity {
    // ...
}

Ok, one problem down.  Now we run into the issue of the type mapping value itself (e.g. “employee”, “manager”, etc).  This seems like it should be something AO could handle for us auto-magically, right?  After all, there’s already a hierarchy in place for generating table names from a given entity type, extending this to handle polymorphic mapping values should be trivial.

The problem is that the process of converting an entity type into a table name is non-invertible, meaning that you can’t just feed in a table name and get a valid entity type out the other end.  Information is actually lost in the transition between type and table.  Think about it; the process starts with a fully-qualified class name, strips off the package info, messes with case, special chars and (potentially) plurality.  By the time we get to the result, the table name is so mangled and transformed as to bear absolutely no resemblance to the original type (at least from the perspective of a generic algorithm).

So the current table name generation hierarchy is insufficient for our purposes.  Potentially it could generate the values, but it certainly couldn’t retrieve the type which corresponds with those values.  To solve this problem, we need to introduce a whole new generator to the group: PolymorphicTypeMapper.

All that our type mapper implementation needs to do is define a process by which types are transformed into string values and back again.  We could just rely on storing the fully-qualified class name, but this is both rigid (hard to refactor) and ugly.  No, this is one place where I think we can do something a bit more sophisticated.

It is possible to simply force the users to specify mappings from type to String in the form of a Map<Class, String>, and in the end, this is what our process will boil down to.  However, I think we can add some syntactic sugar to the process which will allow it to default to a de-pluralized (if necessary) version of the table name:

EntityManager em = new EntityManager(...);
em.setPolymorphicTypeMapper(new DefaultPolymorphicTypeMapper(
     Employee.class, Manager.class));

This way, DefaultPolymorphicTypeMapper will auto-generate the mappings based on the classes we pass.  Since we’re statically specifying which subtypes will be used polymorphically, we’re still giving the system enough information to produce an invertible process.  We are coupling our EntityManager initialization a bit to our entity hierarchy.  However, if you’re using migrations, chances are you’ve already taken this plunge.  Anyway, I think it’s about as clean as the syntax can possibly become (with the possible exception of a less verbose class name).

Thanks to the introduction of the type mapper, we can now use our polymorphic hierarchy in the following way:

// ...
Employee employee = em.get(Employee.class, 1);
InsurancePolicy[] policies = employee.getPolicies();
 
for (InsurancePolicy policy : em.find(InsurancePolicy.class)) {
    System.out.println("Found policy with value: " + policy.getValue());
 
    if (policy.getPerson() instanceof Employee) {
        System.out.println("Belongs to an employee");
    } else if (policy.getPerson() instanceof Manager) {
        System.out.println("Belongs to a manager");
    }
}

Okay, maybe a bad example, but the functionality is expressed.  This sort of mapping can be a very powerful tool for reducing code hassle and improving extensibility.  It even works with many-to-many and (the new) one-to-one relations.  With this functionality, ActiveObjects table inheritance is more or less feature-complete.  Unless I’m missing something obvious, this provides about all the reasonable functionality you could possible want from an entity inheritance scheme.

Currently, this feature is just in the SVN trunk/ and slated for release in the upcoming 0.7 build.  There are still a few bugs to be worked out (specifically in the cache expiry mechanism for complex polymorphic many-to-many relations), but everything should be more or less stable and usable.  Enjoy!

You Should Be Excited About Java on Mac

3
Dec
2007

I realize the very last thing I said about Java on the Mac was extremely negative, and I think that still holds.  Apple screwed up, big time.  What I’m talking about is a grass-roots effort to port Sun’s FreeBSD version of Java 6 over to MacOS X.  I’m talking about SoyLatte.

For those of you playing catch-up, SoyLatte was started by a bright guy named Landon Fuller with the expressed purpose of providing a Java 6 implementation for MacOS X 10.5 (Leopard).  It does this by availing itself of Mac’s BSD roots.  Because Darwin is basically a fork of the FreeBSD kernel, many BSD-based application can be easily ported to run in some form on MacOS X.  Sometimes all it takes is a recompilation linking against different libraries.  Obviously a full blown JVM is quite a bit more complicated than GNUChess, but the principle is the same.

The key phrase here is “run in some form”.  Mac applications are legendary for integration, sophistication and smoothness.  I have to admit that this reputation is well merited.  As a credit to Apple’s work on its (now outdated) JVM, this integration even extends to many applications written in Java.  Swing applications on Mac look native (because they’re using native Cocoa widgets, even more native than SWT’s Carbon implementation).  Java applications are also fully AppleScriptable, have access to core services like the application menu, services, file associations, the dock; the list just goes on and on.  This kind of tight integration is exactly what James Gosling was talking about when he said that Apple wanted to do the Java port on Mac themselves.  This kind of tight integration is very difficult for third-parties to accomplish.

Just to choose a comparatively trivial example, consider Swing (I did say comparatively).  Swing/AWT on Mac is peered by Cocoa and extremely performant, a trick that Sun failed to turn on Windows for half a dozen releases (partially succeeding in Java 6).  Swing/AWT on FreeBSD is backed by X11 and can be pseudo-peered using GTK+ widgets.  Now Apple does have a version of X11 bundled with MacOS X, and GTK applications do appear passably Mac-ish, but it’s still not the environment to which Mac users are accustomed.  Even solving this non-blocker issue will require thousands of man-hours and some really clever engineering.

But the point is: it’s happening.  There’s so much momentum behind this project it’s unbelievable.  LandonF is rapidly becoming the equivalent of a blogger household name (think “DHH”), and people are practically lining up to get in on the action.  Now I honestly don’t know how much contributor interest the project is seeing – there are quite a few hoops to jump through – but I know the attention from the community has been staggering.  It’s enough to make me want to buy a Mac just to help out.  :-)

What we’re seeing is virtually unprecedented.  The open-source community is taking a version of Java and independently porting it to another operating system.  Yes in the past we’ve seen projects like GNU Classpath and Harmony which have done clean-room Java implementations, but that’s a totally different problem.  Neither GNU Classpath or Harmony are JCK certified, which means that they’re technically not “Java”.  If Landon and company succeed in getting the FreeBSD Java 6 fully ported to Mac, they probably won’t face this issue.  Because it’s basically Sun’s implementation, and thanks to the new community control over the JCK certification process, SoyLatte could be the first third-party Java distribution to actually be “Java”.  This makes it a viable alternative for developers and (more importantly) big companies which are gun-shy on third-party ports.

So this is an incredibly exciting piece of work.  SoyLatte may be one of the most significant open-source projects in the last few years, and we’re seeing it unfold right before our eyes.  If you have a Mac and any extensive knowledge of Java, you should really consider helping out.  Here’s your chance to do something really significant for the future of Java on one of the most rapidly growing platforms on the market.  Those of us on the sidelines can only sit cheer, marveling and history in the making and admiring the power of the community.

In Search of a Better Build System

26
Nov
2007

There’s a consistent problem with developing applications of any reasonable size, a problem which has dated back even before the early days of C.  The problem is that any application of significance will be composed of several source files.  In fact, reasonable applications are often found to be composed of thousands if not hundreds of thousands of files.  Back in the day, it was felt (for some reason which escapes me) that it would be poor practice to type “gcc -Wall -o filename.o filename.cpp” several thousand times every time the app needed to be recompiled.

So from very early on, developers have been writing tools to aid in the build process.  Some of these tools (most of them) were somewhat ad hoc and specialized.  The most common example which springs to mind is a simple script, which handles the compilation:

#!/bin/sh
 
for f in *.c; do
  name=`echo $f | sed 's/.c//'`
  gcc -Wall -o ${name}.o ${name}.c
done

The limitations of such an approach should be obvious.  For one thing, you can only use this script on a single directory which contains all source files.  This is very rarely the case.  More importantly, there is no linking or dependency checking taking place.  This means that with the exception of very simple applications, this script will outright fail every time.  Of course, you could modify the script extensively to hard-code the dependency information, check for file modification, etc.  However, this would be a long, dull process which would have to be repeated for every application you write.  Not a very productive way to spend your time.

And so was born make.  Make has a number of advantages over the hand-scripted method.  It allows for (fairly) easy dependency specification, it will only compile modified files, it lets you ensure everything happens in the proper order, it’s more maintainable, etc.  However at its core, Make is almost exactly a wrapper around the hand-script method.  As such, it suffers from many of the same limitations, such as a cryptic syntax and a dependence on the underlying shell.  Make is a far cry from hand scripting everything, but it’s hardly the silver bullet developers were looking for.

So as the years went by, more and more solutions were devised, though few of them caught on to the extent that Make had.  To this day, Make is still the de facto standard for C and C++ build systems.  Its dominance is so pervasive that I have even found Java applications which are built using Make, though thankfully these are far and few between.  With Java on the scene, attention turned to a new effort which attempted to unseat Make as the reigning champion of the build tools: Ant.

Ant based its syntax on XML, breaking completely with Make’s bash roots and focusing on the task rather than the dependency.  Because of this clean break, and due to the fact that the Ant interpreter itself is written in Java, Ant is entirely platform agnostic.  An Ant build script written for a Java project can be run on any platform, anywhere (as long as Java is installed).  This immediately gave it a huge boost over Make as it finally enabled developers on platforms such as Windows and MacOS 9 (and earlier), platforms without the advantages afforded by a real shell.  Ant’s rise to dominance in the field of Java build systems was so rapid and so completely unchallenged that it still remains the “proper” way to build a Java application.  Every Java developer has Ant installed, and as such it has become something of a lingua franca in build script land.

Unfortunately Ant, like Make suffers from a number of shortcomings.  Its XML syntax for one, while instantly recognizable and familiar to 99% of developers on this planet, poses problems with verbosity and expressiveness.  For example, Ant doesn’t provide any real mechanism for variables, bona fide procedures or any way to execute arbitrary code without a clean break into Java (a custom Ant Task).  While this tends to keep build scripts somewhat uniform and easily understandable (when you’ve seen one build.xml, you’ve seen them all), it also forms a crippling limitation in many ways.  I’ve used Ant a lot in my time, and let me tell you it can be a real pain.  For simple builds (javac a bunch of source files, copy one or two resources, zip the result, etc) it’s quite sufficient, but headaches set in when dealing with anything complex like chained builds, subprojects or library dependency management.  You can make it work, but it’s not pretty.

The Maven project was started to try to address some of these problems (among other things).  Maven provides full-stack dependancy management (even resolving and downloading third-party libraries), build management, conventions enforcement, IDE interop and so on.  A number of people would say that Ant is completely superceded by Maven, and that Maven is the only way to go for any new Java project.  Unfortunately, like so many successful Java projects of its day (a few examples Spring to mind), Maven refused to maintain its focus.  Instead of being an incredibly simple build system and dependency management tool, Maven has tried to branch out and become the all-encompassing tool to solve everything.  I know I haven’t even scratched the surface of its capabilities in my limited exposure, but I can say that I’ve seen enough.  Maven is amazing, but way way to invasive for my tastes.  It has a knack of making the simple things cryptic, the hard things harder and the complex things impossible.  (by impossible I mean without resorting to hackery like invoking Ant from within Maven or calling out to a shell script)  Now I realize flame wars have been fought on this very subject, but I have to conclude that Maven is just too much and too overwhelming for easy use (and hence, wide adoption).

Fortunately for me, the rise of dynamic languages has brought about some wider options.  Ruby in particular has become a favorite for many different build tool projects (Rake, Raven, etc).  Most interesting is the effort underway to provide a “non-sucky Maven”.  The Buildr project, currently in incubation at Apache, is basically seeking to be a build system which enables trivial application of the most common case (builds and dependencies), as well as the flexibility of a Turing-complete language (Ruby) to make possible just about any build task, no matter how esoteric.

Buildr’s promise is indeed alluring, and at first glance it seems to deliver.  The DSL syntax of the build file is intuitive and easy to grasp.  With this it bundles the full power of Maven, allowing it to be a drop-in replacement for any pre-existing Maven project.  Well, almost.  Buildr doesn’t allow for things like dependency checkout from a source code repository.  It also retains one of Maven’s biggest failings in that it unduly enforces a rigid directory structure.  While it is possible to override this restriction, Buildr’s documentation isn’t exactly clear on how, and to be honest I still haven’t figured out how to get some things working.  Buildr is promising, but not perfect.

Another flaw suffered by all of the new, “avant garde” build tools is that not all of them can be expected on every developer’s machine.  Back in the days of Make and Ant, every developer knew that every other developer could handle a build.xml file and use it to get a fully functional build out the other end.  Unfortunately, while Maven has made tremendous strides in popularity, it is still no where near as ubiquitous as Ant.  Buildr is even less common, additionally requiring the separate installation of a full Ruby runtime, as well as the “buildr” gem.  These considerations are less significant for a small commercial product, where all of the developers are in close contact and outside interference is rare.  However, for the open-source project, standardization in the required tools is critical, otherwise new developers would have no way to contribute.

Unfortunately it’s a bit of a Catch-22.  Even assuming Buildr manages to make good on its promise of being “a build system that doesn’t suck”, it has to gain in popularity before it will be accepted as the de facto standard for Java project builds.  But to gain popularity, Buildr must be accepted by the community.  It’s a tightly knit, closed circle driven by managers remaining content with “the way it’s always been done” and developers refusing to chance the success of their project on the hope that all parties concerned will also show forward thinking in their tool set.  I really don’t envy the Buildr project leads in their task to promote their tool.

So where does this leave me?  Practically speaking, I’m still going to stick with Ant.  Buildr may be interesting, and Maven may be powerful, but neither is the standard yet.  Perhaps even more importantly: I’m lazy.  I know Ant.  I know it very well and I would have to see some pretty clear benefits (and an easy introductory road) to switch my build system of choice.  Right now, I don’t see either of those.  Maven is infamous for having a very steep learning curve.  And as I mentioned before, Buildr’s documentation leaves something to be desired.

I want to help usher in the next era of Java development as much as the next guy.  But I’m not willing to sacrifice the now for the sake of a future which may take a totally different form when it arrives.  So I will (reluctantly) stick with my old standby.  Perhaps someday I’ll come across a build tool which really impresses me enough to make me switch.  Until then you can continue to listen to me whine and complain about the difficulties of whipping Ant into shape.  How lucky for both of us.  :-S

Table Inheritance with ActiveObjects

19
Nov
2007

The main obstacle in building an ORM is deciding how to map between a class hierarchy and a database table set.  While this may seem fairly clear cut in many situations, it’s unfortunately not so easy once you get into more complex issues like inheritance.

At a basic level, tables are classes.  It makes sense, right?  A class defines a structure which is instantiated and populated with data.  A table defines a structure into which data is inserted, one set per row.  Superficially, these two concepts sound more-or-less identical.  The differences creep in when you look at things like a class hierarchy.  Classes have the ability to inherit attributes from a superclass.  Thus, if class A inherits from class B, class A has everything that class B has (simplistically put). 

Unfortunately, database tables have no such capability.  You can’t define a table which has everything a “supertable” has.  Nor can you select data out of a “subtable” as if it were a supertable (polymorphism).  This lack of capability creates a disconnect between database structure and object-oriented class structure.

As with all of these “little differences” (between languages and databases), many solutions have been tried, none of them very successfully.  One of the most popular ways to solve the problem is to use separate tables for the supertable and subtable.  Then, whenever one SELECTs from the subtable, a JOIN is used to include the inherited row from the supertable in the result set.  In principle, it sounds right.  After all, this is how C++ handles inheritance.  However, in practice it becomes rather unwieldy.

To start with, JOINing every time you perform a simple SELECT is both inefficient and annoying.  Maintaining two separate rows is also a difficult problem to keep up with.  Inevitably, the data gets a bit out of sync and the whole thing falls apart.  Granted a good ORM will prevent this from happening in the first place, but ORMs are not the exclusive means for accessing database schemata.  Often times your schema will be in use not just by your application, but also by a web site, a demo utility and random DBAs who refuse to enter data in any way other than hand-written SQL.  In short, table inheritance using JOINs is clunky, unmaintainable and really messes you up down the line.

Another, more conservative way to map inheritance is inclining, where every subtable contains all of the fields which would be in a supertable.  Thus, if table A and B inherit from table C, table A and B are created with all of the fields that would have been in table C, and table C isn’t created at all.  Technically speaking, it’s not inheritance, just a slightly more centralized way to specify fields.  However, this technique is much more in line with how a database schema would normally work if designed by hand, and that’s what ORMs are supposed to simplify, right?

The ActiveObjects Approach

As you have have guessed from my comments, I really lean toward the inline strategy.  I think this works best in a practical environment and is far more maintainable down the line.  Thankfully, this strategy is considerably easier to implement than JOINing.  Syntax-wise, inheritance is used like this:

public interface Person extends Entity {
    public String getFirstName();
    public void setFirstName(String firstName);
 
    public String getLastName();
    public void setLastName(String lastName);
}
 
public interface Employee extends Person {
    public String getTitle();
    public void setTitle(String title);
 
    public short getHourlyRate();
    public void setHourlyRate(short rate);
 
    public Manager getManager();
    public void setManager(Manager manager);
}
 
public interface Manager extends Person {
    @OneToMany
    public Employee[] getPeons();
 
    public long getSalary();
    public void setSalary(long salary);
}

A fairly standard, object-oriented interface hierarchy, right?  Logically it makes sense.  This is how ActiveObjects would represent such a hierarchy in the database:

employees
id
firstName
lastName
title
hourlyRate
managerID

 

managers
id
firstName
lastName
title
salary

So basically inheritance in ActiveObjects is just a mechanism which allows the definition of common fields in a single place.  There’s no real polymorphism (that is to say, you can’t INSERT an employee where a person is required, since there is no “people” table).  The idea is: keep it simple stupid.  In fact, ActiveObjects would happily generate a table to correspond to Person if we asked it to, since as far as it’s concerned it’s just an entity like any other.

Of course, there are quite a few serious disadvantages to this approach.  For one thing, without polymorphism or actually centralizing the fields in a common table, inheritance is just an illusion.  From a database standpoint, the tables aren’t really related in any interesting way.  You’re still duplicating fields in the database (though not duplicating data), though since the duplication is all handled by the ORM, it’s not too much of an issue.

For me though, it all comes back to the decision I made to not make the schema over-complicated.  To ensure that no matter what the object hierarchy, it could be represented in the database (assuming it’s valid) without undue weirdness.  Keep the schema simple, make it easy to do stuff outside of the ORM.  The ORM should be a liberating too, not a constraining one.

I realize not everyone agrees with this particular style of table inheritance, so maybe at some point in the future ActiveObjects will allow configuration in this area.  But for the moment, the uncomplicated schema is the way to go.  :-)   Enjoy!