Tools Road Map
IntroductionWhile working on improving the CodeGenerator for Hibernate, I've been examining all the other tools sourrounding Hibernate - just to see what they can do now and to get some thoughts on where we are heading (or at least could be heading). This "document" lay out the current state of the tools as I see it and it also includes an description of where I (Max) would like it to go - As always, you are more than welcome to comment on this, either here, on the mailinglist or in the forum. Also feel free to correct or even add information relevant to the Hibernate tools.
Current stateCurrently we got the following tools:
- CodeGenerator
- SchemaExport / SchemaUpdate
- MapGenerator
- ReverseEngTool
- Hibernate XDocLet module
The following image should provide you with an overview on which role the different tools has in the generation and derivation of .hbm.xml, .java and other files. <hook src="hib_images/community/hibernatetoolscurrent.png" style="position: relative; padding-left:20%;">embed</hook> As you can see, Hibernate is actually pretty well covered in regards to supporting any kind of development process (as also described here Development Process from Hibernate doc ) Yes, from the diagram, the toolset currently allows full roundtripping. The weakest link is in the reverse engineering of existing database tables. But in fairness, that step will always require a great degree of human intervention anyway. - Gavin But there is still room for improvement :)
CodeGenerator The codegenerator has matured greatly the last few months and weeks and is more or less capable of deriving all the java class needed for any hbm.xml file (please correct me if i'm wrong here!).
Shortcomings in 2.1.2(in no particular order)
- It is somewhat rigid regarding the codegeneration - any change has to be added to the BasicRenderer
- Could support references to proxies better.
- Does not generate referenced proxy classes.
- It has grown rather large, and the main files has quite big methods and redundant code, it needs a refactoring :)
Shortcomings in older versions
- There is no support for having generated classes that implement and/or extends a certian interface/class (e.g. MyPersistentObject as a common interface to primary keys and version information). (Now supported via <meta>)
- Limited to the hibernate.dtd which primarily focuses on OR mapping (which it should do!) - thus it is hard to provide codegen specific information via the hbm.xml. (Now supported via <meta>)
Note: Do not see the number of short-comings listed here as an indication that the codegenerator does not work. It does, and is very stable and functional. The reason for the "long" list of shortcomings is primarily because I know the CodeGenerator better compared to the other tools.
SchemaExport / SchemaUpdateFairly complete and stable generation of proper SQL DDL (create table ...) from hbm.xml files. Some of my co-workers are using this constantly in their buildprocess and have not heard any complaint yet :) Furthermore I have not seen any request or bugreports for this tool lately. SchemaExport is very mature and complete and I don't expect to see any big changes to the current code / functionality. It is unique in the fact that SchemaExport is integrated into and maintained as part of the core Hibernate functionality / test suite. SchemaUpdate is much less mature and may or may not be practical in real life situations. Yes - I looked for some docs on what SchemaUpdate actually does - does anyone know ? :) I can see in the sourcecode that it invokes some alter statements, but did not completely grasped how much it could "discover" correctly - Max Schema Update works just like SchemaExport, but before creating a table it checks if the table already exists, and if it does it just adds missing columns. -Chris
ShortcomingsNone that I know of. I couldn't get the SchemaUpdate to work correctly with PostgreSQL using the 7.3 jdbc 3.0 drivers. I also tried the development jdbc drivers too, but SchemaUpdate doesn't detect that the tables are already created, instead it just attempts to create a table that is already there. If anyone knows how to solve this, please email me at dean.mao@ichotelsgroup.com. Thanks! -- Added by Dean Mao on Sept 26, 2003 I am also having problems with it PostgreSql 7.4 -- markmansour@yahoo.com
ReverseEngTool A newcomer to the tool set. It provides a basic mapping from JDBC to one or more hbm.xml files. The mapping contains a class per table and lists the primary key and properties.
Shortcomings(in no particular order)
- Only lists id, composite-id and properties.
- Does not "discover" foreign keys references.
- Requires definitions of foreign keys.
MapGenerator I have very limited experience with this tool, but it seems a good starting point if you already got your java classes in place. The original concept of this tool was for something that would help users "get started" with a skeletal mapping document. In practice it has not proved very useful for actual development because the generated mapping still needs to be hand edited. The basic problem is that a .class file does not contain enough information to be able to generate a mapping (if it did, we wouldn't need the mapping metadata in the first place). Now that XDoclet gives us a way to embed metadata in the Java source, this tool should probably be considered deprecated for serious development work. (It might still be useful for something like the Eclipse plugin linked below.) - Gavin
Shortcomings
- the mapping file must be hand-edited, so regeneration is dangerous
- collection mappings must be coded by hand
- table names, column names must be coded by hand
Hibernate XDocLet module A tool that was born in Hibernate, but has now been incorporated into the xdoclet core ( http://xdoclet.sf.net ). Is pretty mature and is actively developed.
Shortcomings
- no support for composite identifiers - we would need to add both a @hibernate.composite-id tag and a @hibernate.column tag
General shortcomings
- CodeGenerator and Hibernate it self uses two different methods for parsing the hbm.xml file. Primarily that the Hibernate parser relies on being able to use reflection on the related classes. The CodeGenerator can of course not do this. This makes keeping codegenerator and Hibernate in sync a "challenge" :) Same is true of XDoclet module, actually. - Gavin
- The toolset is heavily under-documented.
The FutureSo, what should the future bring? Well, I would like the Hibernate tools to be so complete that each possible conversion/generation step is as complete and flexible as possible - and keep on following the "keep-it-simple" philosophy. The next sections describe some of my ideas :)
MiddleGen - the next generation of ReverseEngToolI would also like to see that we utilize existing "generation"-tools out there if at all possible. One of these are MiddleGen which really looks promising. It is basically a tool that builds up a data model based on an existing JDBC database. It then provides a interactive GUI where one can provide additional information about cardinality between entities and such (note: this is also possible to do via simple ant tasks). It's main force is that it is very easy to extend via its plugin framework! And it would be great if there was an Hibernate plugin for it! If we were to build a plugin for MiddleGen we would actually have a very powerful alternative to the ReverseEngTool (primarily because MiddleGen discovers relationships defined by foreign keys and allows user customization of these relationships). Thus to avoid building something that has already been done I would suggest that we took some of the Hibernate specifics in ReverseEngTool and build an plugin for MiddleGen instead. I agree with all this. Middlegen does seem to be gaining a fair amount of mindshare and I think its undesirable for our own project to be maintaining GUI-based tools. I wonder how much work is involved in writing a MiddleGen plugin. I took a look at it, and it actually looks quite easy. One can get very far by just providing a velocity template that utilizes the existing data model build by MiddleGen - I did a basic one in 10 mins, the mapping was almost as good as our existing ReverseEngTool with regards to identitfying id's and properties - The only thing missing was the Hibernate specifics, such as which id generator to use and such. For this one needs to write a small plugin that provides that information. And here there 5-6 plugins with sourcecode that could work as inspiration. - Max I think its desirable that Hibernate integrate with existing best-of-breed open source tools like XDoclet and MiddleGen, rather than trying to build everything ourselves. This lets us concentrate on being a good O/R mapper (and do one thing well). It also helps users leverage their knowledge of existing tools when migrating to Hibernate. - Gavin MiddleGen has been discussed on the forum and developer list previously but noone seems to have "picked it up" (to bad....). In the discussion it was mentioned that the "best" way to write an Hibernate plugin, would be to have it generate .java sourcecode with XDocLet comments which then could be used to build the actual hbm.xml file. This is great, but I would suggest that we ALSO wrote an plugin that generated the hbm.xml file directly as that would allow the user to go either way. It is illustrated in the following figure: <hook src="hib_images/community/hibernatetoolsfuture.png" style="position: relative; padding-left:20%;">embed</hook> Anyone up for this challenge? (I've looked at middlegen and it should be quite easy to do ... I'm just to darn busy with the codegenerator :) There is another related tool UML2EJB which generates xdoclet-marked classes for EJB & XDoclet use from .xmi files. Eventually I will produce templates for it
Codegenerator of the Future Near future:
- Add support for providing more information to codegenerator via the hbm.xml. (Now supported via <meta>)
- Suggestion by Gavin on how to do this (notice the <meta> tag):
<class name="Foo" ... >
<meta attribute="description">JavaDoc comment for Foo</meta>
<meta attribute="base-class">AbstractPersistent</meta>
<meta attribute="generated-class">FooBase</meta>
.....
<property name="bar" type="serializable" ....>
<meta attribute="description">
JavaDoc comment for getBar()
</meta>
<meta attribute="java-type">java.lang.Object</meta>
</property>
.....
</class>
- With support for <meta> comes: (And this is now supported!)
- Making codegenerator generate an abstract super class, instead of the concrete class. Makes it possible to add business-methods/functionallity to entity classes without having the codegenerator overwrite your changes.
- Add support for having entities extend user-chosen base classes and interfaces.
- Add support for inserting javadoc.
Later:
- Replace BasicRenderer with a velocity template - will make it easier to customize, but requires a better "classmapping" model. (maybe consider MiddleGen or Torque as the driver for this ? nah - it would require additional info besides the hbm.xml file) Not convinced that using XSLT or a velocity template would actually reduce the amount of code. CodeGenerator is not currently a very "big" in terms of lines of code. On the other hand, introducing a dependency upon velocity might make it harder to configure + get running. - Gavin You might be right on this one. It's just that the BasicRenderer class is more and more becoming simple "dumping" of the ClassMapping, and this could be done better by an velocity template (it is more readable). But I agree on keeping this on the rocks for a while - Max
- Add option for generating interfaces (needed for Dynamic Proxy support)
- Make it (and Hibernate) use common parsing of hbm.xml (requires changing the current parser in Hibernate - a major "challenge" :) My view is that this is too much work to be worth the effort at this stage. As far as delivering useful functionality to the users, there is other much lower-hanging fruit. - Gavin Yes - I agree. - Max
- Add option for generating add and remove methods for collections. Yes, very desirable. - Gavin
The simple version:
public void addUser( User user) {
users.add(user);
}
public void removeUser( User user) {
users.remove(user);
}
The "advanced" bi-directional version:
public void addUser( User user) {
users.add(user);
users.setGroup(this);
}
public void removeUser( User user) {
users.remove(user);
users.setGroup(null);
}
Wilder Ideas :)
- Eclipse plugin
- There exist a raw version at Eclipse plugin screenshot, Eclipse plugin src which mimics the MapGenerator. Just using Eclipse AST instead of reflection.
- Idea: HQL console with code completion and table view of the result :)
|