Organically grownOrganically grown

Databinder started off in late 2005 with a simple mission: fill the negative space of Wicket persistence with a priority on factoring out application code.

Java and “serious” programming in general have accumulated a lot of conceptual baggage over the years. Particularly the timeworn task of database interaction has piled one ritual on top of another into a heap of ceremony that, compared to the terseness of inlined SQL in PHP pages that drives most of the web, is a masochistic dogma.

Fairly recently the Spring framework transformed the myriad denominations of Java pattern-worship into a sleek metaphysical cult. Nothing was obligatory, but a spiritual misstep could ruin your chances of transcendence when the spaceship comes for the truly devout. Around the same time, Rails was making mindshare inroads by mimicking the rain dances of professional programming (to make everyone comfortable) while leveraging Ruby to obscure the taboos it broke in factoring out application code (to make everyone productive).

And Wicket was just being its awesome self. Wicket contains a lot of structure that, while not bound to any particular persistence mechanism, facilitates loading objects as they’re needed and detaching them when a request cycle completes. This is an unfamiliar concept to most programmers, and for new users the task of implementing it correctly—something any application requires—can be perplexing.

Rolled steel for making boilers

There are conservative ways of binding Wicket to persistence layers that strive to offend no popular ideology. You can find examples. The problem is that kowtowing to data model orthodoxy burdens Wicket code enough to kill the fun you’re supposed to be having using stateful web components.

Specifically, a detachable implementation of IModel must know how to load itself, yet those kinds of objects are not really supposed to know how to load themselves. The sacred book says that all objects shall be loaded through some Data Access Object that is named sorta like those objects. And ever since approximately Spring, you’re not even supposed to construct this thing yourself: it’s supposed to be “injected.” Are we having fun yet?

The quickest way to deal with this is to somehow reference your instantiated DAO in a Wicket component (there are ways), then use an anonymous IModel subclass to load the model object from the DAO in a callback. Or, if you dare, you can retain a reference to a wrapped DAO in an IModel, which will not serialize and will produce itself from some context on demand. This eliminates the requirement for an anonymous subclass and significantly cuts down the bulk. Whether or not they’ll still let you board the spaceship after taking a shortcut is hard to say.

The incredible thing is that all of this work is in the name of solving problems that we choose to have. We’re creating droves of DAOs (a separate class and interface for each, as well as a reference in some XML file) and contorting everything to reference them from user interface model wrappers by choice.

Databinder chooses different

The idea with Databinder is that, if you forget about all that nonsense, you can very easily instantiate an IModel subclass that loads itself directly. And here “directly” means not at all directly, because there are already a half dozen layers of abstraction when using any ORM library. So you use those freaking layers to load your freaking model object, and get on with your life. You stop feeling a need to confess to the local enterprise priest after a hundred or so of these:

new HibernateObjectModel(MyClass.class, myId)

The open question was how to extend this approach beyond Hibernate. Since various parts of Databinder were linking to Hibernate in order to cut code in the library and client applications, there wasn’t any obvious way to isolate it.

The standard approach is to abstract-out the actual persistence layer so that shared code can be built around it. This is also the noisy plan for a gazillion-DAO application architecture (though carrying this through to anything beyond ORM zero is decidedly rare), so it’s immediately suspect. It rests on the idea that any persistence technology can be reduced to a few standard load and save operations involving data objects, session factories, and primary keys: a false assumption.

In practice, it’s not even true for existing persistence technologies that you can create a common denominator façade that preserves their strengths, let alone for any conceivable future technology. By limiting potential persisters to those you could easily “swap in,” you’re excluding any significant advancement that is worth switching to.

Faced with such prospects, Databinder remained Hibernate-only for two years.

Reactivation

Well, Hibernate is great and all, but… Maybe it takes the you too far from SQL? Maybe it’s too ambitious in the schemas and class hierarchies it attempts to unify? Maybe its persistence session is not right after all for web request cycles? Maybe we shouldn’t even be using relational databases for things that are more like documents than spreadsheets? Maybe.

It’s hard to use Hibernate vigorously without having these doubts. You start to want to come out of the cave and do a little exploring. Such was the mood when Databinder picked up ActiveObjects. It’s new and, yes, different. It doesn’t have a per-user persistence session. It does draw inspiration from Rails’ ActiveRecord, while leveraging Java for all that it’s worth. It feels a lot closer to the SQL metal. It’s a breath of fresh air.

So! How did we incorporate a new persistence technology? By turning the traditional abstracted-core model inside out. The new Databinder has several functional cores, and infinitely many specific implementation leaf modules.

It’s like, you know, organic

Databinder had already been broken into functional modules: models, components, authentication components, and the application kit. This allows applications to link to only the modules they need. In the new Databinder, each functional module is distilled to a shared codebase that persistence-specific modules build upon. So there are databinder-models-hib and databinder-models-ao building upon the abstract module databinder-models.

The resulting module structure is more like a tree than an onion. Rather than trying to anticipate any possible method of persistence through a core interface, it allows future technology to be added as a leaf module. Realizing the impossibility of flawless centralized planning, it grows organically. (Which would seem to be the latest corporate buzzword, but in this case it is apt.)

Not that the module structure is entirely free of future-constraints. The centralized code in each module necessarily makes some assumptions, and some of those will surely bite back. The most dangerous territory is the authentication components module, where Databinder is at its most impulsive in factoring out traditionally application-level code.

But it works: we have a databinder-auth-compnents-ao that you can use with ActiveObjects the same as databinder-auth-components-hib works for Hibernate. The class hierarchy is a bit kaleidoscopic, but when everything is instantiated you get login, registration, and user admin screens for free (so don’t even think about complaining).

Oh yes, and Cayenne too. Just to make sure that the structure was not hiding some bias for Hibernate and ActiveObjects, this long weekend allowed a few hours to learn some Cayenne and throw together basic support for it. No problem! And once again we see how everything is not like whatever ORM one thinks of as standard. Cayenne has an ObjectId class that includes whatever the primary keys may be as well as the data object’s class. This way, the persistent IModel need only deal with one of those objects instead of id and class objects. It’s a nice touch that Databinder would have missed out on if it shoehorned everything into a Hibernatish worldview.

Still growing

Sorry, none of this is ready to leave the greenhouse yet. Since it has triggered a package reorganization that will break app code, it’s become an opportunity to rethink organizational details in Databinder. And Jon has been contributing some excellent ideas. So these new modules are going to be thrashing around on the trunk for a while where they belong.

But don’t let that stop you from checking it out! Especially if you want to play with and help improve the ActiveObjects and Cayenne modules. And especially especially if you want to add a new persistence module. Please. That would rule.

svn co svn://databinder.net/templates/trunk

That’s where the little starter applications are housed. Don’t worry about the pom.xml in the parent directory, that’s just for deployments. Go into whichever template directory you want, build and run with Maven or Buildr to download everything from the snapshot repository.

And don’t worry about being left behind; the spaceship is just another thing they made up.

Codercomments

You’ve made my day with this post. I’d begun to think that it was just me. Piling abstraction on top of abstraction so that the one common task can be done with zero configuration and one line of code, while every other task of any interest is scorned as a violation of the latest immutable law of software design that someone pecked out on their blog.

It’s why the PHP people are eating Java’s lunch. I’m supposed to start supporting a web development firm next month, the creation of some ordinary websites. I’ve searched high and low for a Java CMS that is open source that could begin to compete with Drupal for features and community. There is a candidate or two, but there are so many misfires.

What do all these abstractions buy us? I can’t find a Java CMS that has anywhere near as many 3rd party modules of WordPress or Drupral. Does it make software extensible? PHP, with it’s hand’s on approach to the strings that make a web application what it is, is apparently better able to foster a plug-in community.

I’m bummed, because I do not like PHP. But in this arena, PHP beats both Java and Ruby with their object layers, in creating the everything and the kitchen sink CMS.

Maybe strings are more adaptable than objects?

Anyway, this is the post that lead me to download Databinder and try it out. I have such respect for a healthy cynicism.

Thanks Alan, glad you enjoyed it. You may be on to something there with pluggable web apps and PHP. It’s hard to build a statically typed OOP interface for plug-ins that’s flexible, particularly if you want to be able to add new plugins without restarting the server. On top of that Java generally lacks the can-do, just hack it attitude you need for a healthy plug-in ecosystem. But I always hope that will change! I wonder if anyone has tried to make an app where Wicket components are added with OSGi modules after deployment; that could be interesting.

I hope you like Databinder. The toolkit is no stranger to abstraction or OOP (being based on Wicket), but all of its structure is strictly in the name of simplifying application code (rather than glorifying itself). If you want a CMS to build sites from largish pre-fab components, obviously you still want something like Drupal or WordPress. But if you want to make a site from scratch using small to mid-size data-driven components, Databinder could fit the bill.

Add a comment