If you don't plan to use the class inheritance structure, it is not necessary to read this article. Please read another article I wrote "Use the Hibernate extension tool HBM2JAVAtask to generate a persistent object class (2.1.2)" according to the configuration file according to the profile, in Chapter 8, Hibernate / Doc / Reference / EN / HTML / Inheritance.html)
The mapping of "one table of each subclass" is like this:
id>
...
...
joined-subclass>
...
joined-subclass>
...
joined-subclass>
clas>
2. Documentation Chapter 5 (Hibernate / Doc / Reference / EN-CN / HTML / MAPPING.HTML)
Allows Subclass and Joined-SubClass to be defined in separate mapping documents, directly under Hibernate-mapping. This allows you to join a new mapping file when you expand your class level. In the subclass map you must specify an extents property, indicate the superclass that has been previously mapped. When using this function, you must pay attention to the sort of the mapping file is very important!
subclass>
hibernate-maping>
3. According to the above two points, it is based on Payment according to Chapter 8, and the Joined-SubClass is now moved. Now the project catalog structure is as follows.
Payment
Can be "
Use the Hibernate extension tool HBM2JAVAtask to generate a profile of the three files according to the profile.
Listening only .HBM.xml file content here.
4.1 payment.hbm.xml
XML Version = "1.0" encoding = "gbk"?>
4.2 CreditcardPayment.hbm.xml
XML Version = "1.0" encoding = "GBK"?>
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
joined-subclass>
hibernate-maping>
4.3 CashPayment.hbm.xml
XML Version = "1.0" encoding = "GBK"?>
joined-subclass>
hibernate-maping>
5. Enter the project catalog in the command line, run Ant, an error, the key prompt is as follows:
Net.sf.hibernate.mappingexception: Cannot Extend Unmapped Class Payment.Payment
6. I don't say anything wrong, I'm boring, just talk about the problem.
6.1 HBM2JAVAtask is looped to the list of profiles, and each file is handled separately, so there is associated class.
6.2 But the CodeGenerator class is not properly, and there is no consideration of file arrangement, because subclasses may be processed before the parent class.
7. The following posts two modified file code. In the modified place, a Chinese comment is added.
7.1 Net.sf.hibernate.tool.hbm2java.hbm2javatask
Package net.sf.hibernate.tool.hbm2java;
Import java.io.file;
Import java.io.printwriter;
Import java.io.stringwriter;
Import java.util.arraylist;
Import java.util.list;
Import org.apache.tools.nt.buildexception;
Import org.apache.tools.ant.directoryScanner;
Import org.apache.tools.ant.task;
Import org.apache.tools.nt.types.fileset;
Import org.apache.tools.nt.types.path;
Import org.apache.tools.types.reference;
Import org.apache.commons.logging.log;
Import org.apache.commons.logging.logfactory;
/ **
* Task for HBM2JAVA (Hibernates Codegenerator)
*
*
* @Author Gbegley and max
*
* /
Public class hbm2javatask eXtends task {
Private static final log log = logfactory.getlog (codegenerator.class);
PRIVATE FILE CONFIGURATIONFILE;
PRIVATE path compileclasspath;
PRIVATE OUTPUTDIR;
PRIVATE LIST FileSets = New ArrayList ();
/ **
* Set a hbm2java
* /
Public void setconfig (file configurationfile) {
THIS.CONFIGURATIONFILE = CONFIGURATIONFILE
}
/ **
* Set the classpath to be used for this compiration.
*
* @Param ClassPath An Ant Path Object Containing The Compiration ClassPath.
* /
Public void setclasspath (path classpath) {
IF (compileclasspath == null) {
CompileClassPath = ClassPath;
} else {
CompileClassPath.Append (ClassPath);
}
}
/ ** Gets the classpath to be used for this compiration. * /
Public path getclasspath () {
Return compileclasspath;
}
/ **
* Adds a path to the classpath.
* /
Public path createclasspath () {
IF (compileclasspath == null) {
CompileClassPath = New path (getProject ());
}
Return compileclasspath.createpath ();
}
/ **
* Adds a reason to a classpath defined elsewhere.
* /
Public void setClassPathref (Reference R) {
CreateClassPath (). setRefID (r);
}
/ **
* Adds a set of files to translate.
* /
Public Void AddFileSet (Fileset Set) {
FileSets.Add (SET);
}
/ **
* Sets the output directory.
*
* @Param Bindirectory Directory
* /
Public void setputput (file outdirectory) {
THIS.Outputdir = Outdirectory;
}
Public void execute () throws buildexception {
List filelist = getTargetFiles ();
IF (filelist.size () == 0)
Return;
"" processing " filelist.size () " files. ");
Try {
"" Building Hibernate Objects ");
// This loop is an error 1,
// for (int i = 0; I // processfile (outputdir, (file) FileList.get (i)); //} / / To modify the ProcessFile method ProcessFile (Outputdir, FileList); } catch (throwable t) { StringWriter SW = new stringWriter (); T.PrintStackTrace (New PrintWriter (SW)); Throw new buildexception ("caused by: / n" sw.toString ()); } } / ** * * * Comment: * The Initial Ant Task Had Some Initial Filtering on The HBM.XML / Java Names To Only Process The NEeded Files. ............... .. * Thus i've removed it and let it be something what hbm2java shouth do. * * * @Return * / Private list gettargetfiles () { List l = new java.util.arrayList (); // DEAL with the filesets For (int i = 0; i FileSet FS = (fileset) FileSets.get (i); File Parent = fs.getdir (getProject ()); DirectoryScanner DS = fs.getdirectoryScanner (getProject ()); String [] files = ds.getincludedfiles (); For (int J = 0; j File Srcfile = New File (Parent, Files [J]); L.Add (srcfile); } } Return L; } / / Modify the method parameters Private void processfile (file outputdir, list file) { List args = new arraylist (); IF (outputdir! = null) { Args.add ("- output =" outputdir.getabsolutePath ()); } IF (ConfigurationFile! = NULL) { Args.add ("- config =" configurationfile; } // Add all files to command line parameters For (int i = 0; i Args.add ((file) FileList.get (i)). getabsolutePath ()); } Try { Net.sf.hibernate.tool.hbm2java.codegenerator.main (String []) args.toarray (new string [args.size ()); } catch (throwable t) { StringWriter SW = new stringwriter (); T.PrintStackTrace (New PrintWriter (SW)); Throw new buildexception ("caused by: / n" sw.toString ()); } } } 7.2 Net.sf.hibernate.tool.hbm2java.codegenerator / * * $ ID: CODEGENERATOR.JAVA, V 1.7 2004/03/22 20:41:47 Maxcsaucdk EXP $ * / Package net.sf.hibernate.tool.hbm2java; Import java.io.file; Import java.util.arraylist; Import java.util.hashmap; Import java.util.iterator; Import java.util.list; Import net.sf.hibelnate.mappingexception; Import net.sf.hibernate.util.dtdenTyResolver; Import org.apache.commons.collections.multihashmap; Import org.apache.commons.collections.multimap; Import org.apache.commons.logging.log; Import org.apache.commons.logging.logfactory; Import org.jdom.document; Import org.jdom.element; Import org.jdom.input.saxbuilder; Import org.xml.sax.errorhandler; Import org.xml.sax.saxparseException; / ** * * / Public class codeGenerator { Private static final log log = logfactory.getlog (codegenerator.class); Public static void main (String [] args) { IF (args.length == 0) { System.err.println ("No Arguments Provided. Nothing to do. EXIT."); System.exit (-1); } Try { Arraylist mappingfiles = new arraylist (); SAXBUILDER Builder = New Saxbuilder (TRUE); Builder.sentityResolver (New DTDENTINTYRESOLVER ()); Builder.setdler (New Errorhandler () { Public void error (SAXPARSEEXCEPTION ERROR) { Log.Error ("Error Parsing XML:" Error.getsystemId () '(' Error.getLinenumber () ')', Error) } Public void fatalerror (SAXPARSEEXCEPTION ERROR) { Error (Error); } Public void warning (saxparseException error) { Log.Warn ("Warning Parsing XML:" Error.getsystemId () '(' Error.getLinenumber () ')'); } }); String Outputdir = NULL; List generat = new arraylist (); multimap globalmetas = new multihashmap (); // Parse Command Line Parameters For (int i = 0; i IF (args [i] .startswith ("-")) { IF (args [i] .startswith ("- config =")) { // Parse config XML file Builder.SetValidation (FALSE); Document Document = Builder.Build (New file (args [i] .substring (9))); Globalmetas = metaattributeHelper.loadandMergeMetAmap (Document.GetrooteElement () (), NULL); ITerator generateElements = document.getrootElement (). GetChildren ("generate"). Iterator (); While (generelements.hasnext ()) { GENERATORS.ADD (NEW Generator ((Element) "); } Builder.SetValidation (TRUE); } Else IF (Args [i] .StartSwith ("- output =")) { Outputdir = args [i] .substring (9); } } Else { MappingFiles.Add (args [i]); } } // if no config xml file, add a default generator IF (generators.size () == 0) { GENERATORS.ADD (New Generator ()); } Hashmap classmappings = new hashmap (); Builder.SetValidation (TRUE); // This loop is an error 2 / / Change to only handle Class mapping Iterator it = mappingFiles.ITerator (); it.hasnext ();) { // Parse the mapping file File file = new file (String) iter.next ()); Log.debug (file.getabsolutepath ()); Document Document = Builder.Build (file); ELEMENT ROOTELEMENT = Document.getrootElement (); Org.jdom.attribute a = rootElement.getaTribute ("package"); String pkg = NULL; IF (a! = null) { PKG = a.getValue (); } MappingeElement me = new mappingelt (rootElement, NULL / ** TODO-HBM2JAVA: - Should Be config.xml ** /); Iteerator classelements = rootelement.getchildren ("class"). Iterator (); MultiMap mm = metaattributeHelper.loadandMergeMetAmap (RootElement, globalmetas); HandleClass (PKG, ME, Classmappings, Classelements, MM, FALSE); } // Copy the previous loop // Handle Subclass and Joined-Class mapping Iterator it = mappingFiles.ITerator (); it.hasnext ();) { // Parse the mapping file File file = new file (String) iter.next ()); Document Document = Builder.Build (file); ELEMENT ROOTELEMENT = Document.getrootElement (); Org.jdom.attribute a = rootElement.getaTribute ("package"); String pkg = NULL; IF (a! = null) { PKG = a.getValue (); } MappingeElement me = new mappingelt (rootElement, NULL / ** TODO-HBM2JAVA: - Should Be config.xml ** /); MultiMap mm = metaattributeHelper.loadandMergeMetAmap (RootElement, globalmetas); Iteerator classelements = rootElement.getChildren ("subclass"). Iterator (); HandleClass (PKG, ME, Classmappings, Classelements, MM, TRUE); Classelements = rootelement.getchildren ("Joined-Subclass"). Iterator (); HandleClass (PKG, ME, Classmappings, Classelements, MM, TRUE); } // Generate Source Files Iterator itrator = generatrs.iterator (); item.hasnext ();) { GENERATOR G = (Generator) orerator.next (); g.setBaseDirName (Outputdir); g.Generate (Classmappings); } } Catch (Exception E) { E.PrintStackTrace (); } } Private Static Void Handleclass (String ClassPackage, MappingeLement Me, Hashmap Classmappings, Iterator Classelements, MultiMap MM, Boolean Extendz) throws mappingexception { While (Classelements.hasnext ()) { ELEMENT CLAZZ = (Element) Classelements.next (); IF (! extendz) { Classmapping CMAP = New ClassMapping (ClassPackage, Clazz, ME, MM); Classmappings.put (cMap.GetfullyqualifiedName (), CMAP); } else { String ex = Clazz.gettributevalue ("extends"); IF (EX == NULL) { Throw new mappingexception ("Missing Extends Attribute on <" CLAZZ.GETNAME () "Name =" CLAZZ.GETATTRIBUTEVALUE ("Name") ">"); } Classmapping Superclass = (Classmapping) ClassMappings.get (ex); IF (superclass == null) { Throw new mappingexception ("Cannot Extend Unmapped Class" EX); } Classmapping Subclassmapping = New Classmapping (ClassPackage, ME, Superclass.getClassName (), Superclass, Clazz, mm); Superclass.addsubclass (subclassmapping); } } } }