On Tue, 2009-06-09 at 17:11 +0200, Francis Galiegue wrote:
Hello everyone,
During the last two weeks, I've been developing a small framework
allowing to create mappings on the fly, all the while allowing
existing sessions to "fail gracefully" (ie, if their session fails to
find a previously mapped column or table, they try with a newer
session). I don't use POJOs, so this makes it relatively easy.
This means I have to do DDL on the fly. Steven Ebersole has pointed me
to the Schema* classes in org.hibernate.hbm2ddl. The current abilities
include adding a table, adding columns to a table and removing a table
(a Configuration object with only the validated mapping of the table
to drop will do the trick nicely). But the DDL capabilities are
lacking:
* Hibernate won't drop a column, by choice, and it currently doesn't
give the user a choice because it cannot do so internally AFAICS;
* it won't add indices when requested, even with hbm2ddl=update;
And others.
Steven has pointed to a Jira task talking about an overhaul of the
Dialect abstract class and all its derivatives, because for one, the
Dialect doesn't provide "purpose oriented" capabilities, just one big
lump of methods. After looking at the code (3.3.1), I can see that
this is the case: for instance, there's no separation between DML and
DDL.
Well the JIRA[1] to which I pointed you does not really go into this
per-se. It is more talking about potentially changing the way DDL is
created to use a delegate. Currently what happens is that the mapping
objects (Table, Index, etc) all know how to create DDL there own DDL.
The tie-in with Dialect here is that they coordinate with the Dialect to
figure out its capabilities and syntax. What I'd rather see is an
externalization of this DDL rendering. There are many parts to this and
it is in no way trivial. But the basic "externalize the DDL generation
code" should not be overly complex.
I too had been considering some similar form of cleanup. The ones I had
considered were things like grouping together various "purpose oriented"
methods into componentized contracts. The ones I mentioned to you to
give example were the methods pertaining to a dialects IDENTITY support
and its sequence support. So I'd imagine something like:
public interface IdentitySupport {
public boolean supportsIdentityColumns();
public boolean supportsInsertSelectIdentity();
...
}
public interface SequenceSupport {
public boolean supportsSequences();
public boolean supportsPooledSequences();
...
}
The Dialect contract could then be changed to return these contracts.
But this is all really secondary to what you want to achieve. For your
purposes, you are really just interested in the DDL generator piece.
For that I had envisioned asking the Dialect to get its DDL generation
delegate; maybe something like:
class Dialect {
...
public DDLGenerator getDDLGenerator() {
return ...;
}
}
But I never got the chance to completely think this all through. There
are lots of design questions that need to be addressed. Stuff like does
the delegate contract allow for both create/drop and alter usages? Or
do we ask the Dialect for a delegate for each usage? At what
granularity do we generate DDL commands? And if say at the granularity
of each Table etc, how do we account for say a table DDL command which
includes creating the PK versus one that does not (and therefore needs
separate DDL)?
Anyway, that's about as far as I got.
[1]
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1083
--
Steve Ebersole <steve(a)hibernate.org>
Hibernate.org