(I had to scoot out the door to catch my bus before I could finish that last entry.)
Still thinking out loud here...
Currently we generate about 500+ classes and interfaces, and 600+ deployment descriptors. The amount of generated information is only going to go up as we add more functionality to the system.
The tricky part is how to integrate the generated code and the custom code, particularly in a staticly-typed language like Java. This issue will only get worse as we add more classes and relationships. It's possible to just have custom functionality in a separate file that gets pulled in when the class gets generated, and the user doesn't know the difference. But that's difficult to test and for non-trivial methods, difficult to write.
I feel obliged to mention here that, of course, little of this would be a problem in Perl. But when you're working in a language you need to think in its idioms and patterns.
If I wanted to I could just have all relationship methods return a Object, but then you have to do a cast every time you call something. I consider excessive casts to be one of those "code smells" the XP folks talk about -- it's fine for the Collections API (Lists, Iterators, Maps, etc.) because that's one of the trade-offs (at least until generics/templates come), but not for classes you create unless you have a darned good reason.
In addition to this, I'd like to enable clients to have a simple, unified interface to all functionality a "business object" supports, and enable this interface to support both generated and non-generated code. (Without the code generation wrinkly, this is generically known as a "Business Delegate" in the relevant pattern literature.) Again, with multiple inheritance this wouldn't be an issue: just have the delegate inherit from as many custom and generated classes as necessary.
So instead we need a pseudo-proxy interface, where the delegate gets a request and hands it off to the right place for processing. Not too difficult, except I'm still bitten by the typed return values -- even though it's acting as a proxy the delegate still needs to know the return values of various methods, even if they're generated.
And all the time I'm thinking 'simplify, simplify'... More later, when things are working.
(Originally posted elsewhere)