[FSF Associate Member] View Annang Sowah's profile on LinkedIn

Monday, 6 January 2014

Programming - Java Object-Relational Mapping: Using JBoss' Hibernate SchemaExport tool to generate DDL from Entity Classes and Hibernate Mapping Files

Happy new Year, World J

1. Introduction 
I would take you through how to use Java classes (powered by JBoss' Hibernate) to build a database on the fly. I would present a subsequent post on how to use Netbeans to auto-generate Entity and Mapping Files from a datasource. 

There is every reason not to build your database manually for reasons below: 
    ·         many times you may have little information about your eventual deployment environment. 
    ·         truly service-oriented applications are database agnostic ("database unaware").

 Note: The Linux OS is the development environment I would execute command line scripts. 

I would use the Apache Derby/JavaDB lightweight database  for this tutorial. This database is empty awaiting the schema creation from using Hibernate tools.

These solutions fundamentally are not database nor OS dependent-it should work across all environments.

Fig. 1. The empty application database.

2. Process:  
To create a database straight from code using Hibernate ORM (simply, an implementation of JPA),
one needs 3  inputs i.e.
·             · Hibernate Configuration file i.e. Hibernate.cfg.xml
         ·  The Hibernate mapping files e.g. Tag.hbm.xml
         ·  Java  Entity class adorned with persistence annotations e.g.  @column
       See details below.
2.1. Hibernate Configuration file: This contains the database connection information and other hibernate specific parameters as sampled below:  

    Fig. 2. Content of Hibernate Configuration File.

      As you can observe, it also features the various HBM files (with full package location stated) we need a input. Also remember that these 2 properties must be defined to have, respectively, a persistence session  and schema manipulation enabled i.e. hibernate.current_session_context_class and  hibernate.hbm2ddl.auto.

   2.2. The Hibernate MappingHBM, files: These are needed to model the 4 database tables are below listed Posting.hbm.xml , Poster.hbm.xml, SysUser.hbm.xml and Tag.hbm.xml.

      Note: These were created manually, kindly see my related blog post on how to auto-create HBM files from Netbeans.

      Take a look at the content of the sampled Tag.hbm.xml file.  This content describes the signature of the database table to be created (with the complement of the Tag entity class in next section). 

Fig. 3. Content of a Hibernate mapping file modeled to mimic a Tag relational entity.

      Note: see other blog posts on how to auto-create the mapping file this time around using the Netbeans Hibernate wizard.

    2.3 Java Entity classes: A sampled entity, Tag.java, has been scripted below

Fig. 4. Content of a Hibernate Entity modeled to mimic the desired Tag Table.
     Now that we are done with the setup of the needed input files, we move on to the execution phase    

    3. Execution:
    With the various inputs done we would use Hibernate’s HBM2DDL tool to create the database using 1 of the options available below to run the SchemaExport.
1.       Invoking SchemaExport  from “Java Main class”
2.       Running from the command line

3.       Running the SchemaExport from ant build scripts.

     3.1. Invoking HBM2DDL SchemaExport  from the Java main class

      Create a class, e.g. SchemaCreator.Java,  to serve as the point of invocation of the schema creation or SQL DDL generation. This class makes use of the persistence session created by the HibernateUtil java class. The HibernateUtil class is a specialised class, made use of by the Hibernate ORM framework, which can contain configurations other than the settings in the hibernate.cfg.xml that the framework creates a persistence session from. The location of hibernate.cfg.xml is shown located at the root of your java package structure as shot below.  


    Fig. 5. Content of a HibernateUtil Java file.

   The HibernateUtil class is detailed below.

     Fig. 6. Content of a HibernateUtil Java file.

      The SessionFactory creation from a hibernate.cfg.xml file is performed by the statement below, as shown by the screenshot above.

      SessionFactory  sessionFactory = new Configuration().configure().buildSessionFactory();

      Note: To have the session created from a hibernate.cfg.xml located in another location as desired,  use below code.
     sessionFactory = new Configuration().configure("<CUSTOM_DIRECTORY>/hibernate.cfg.xml").buildSessionFactory();

     You can also add extra configuration parameters by using the instance methods addResource(~)  and addProperties(~) on the Configuration class.



Fig. 7. instance methods of the Configuration class.
        3.1.1 Invoking the schema creation from the main class SchemaCreator java class
     Fig. 8. Content of SchemaCreator invocation class

    Note: The above class principally uses two static objects - SessionFactory and Session.
    sessionFactory = HibernateUtil.getSessionFactory()//fetches session details from configs in HibernateUtil class
    session = sessionFactory.getCurrentSession(); //does loading of application session from Hibernate to be used for searches, updates and saves of entity objects in an application.
     Proceed to compile the above class and execute the class file to get the output below  

Fig. 9. Output of execution of SchemaCreator

    Perform a refresh of the data schema to see the new tables created in your database (remember, the connection parameters and more were stated in the hibernate.cfg.xml file).

Fig. 10. Database loaded with tables modeled from mapping files and entities

3.2.   Running  SchemaExport  from the command line
The syntax is stated below

3.2.1 This a java class invocation from the command line
      java -cp 'hibernate_classpath'  org.hibernate.tool.hbm2ddl.SchemaExport options  my_hbm_mapping_files                                                                                                 
     hibernate_classpath  = the runtime resources needed by hibernate i.e. dependent classes and jar files
     my_hbm_mapping_files = the location of all the *hbm.xml files
     options = this states the various command line parameter the SchemaExport tool  i.e. 

         do not output the script to stdout
         only drop the tables
         only create the tables
         do not export to the database
         output the ddl script to a file
         read Hibernate configuration from an XML file
         read database properties from a file(alt to --config)
         format the generated SQL nicely in the script
         set an end of line delimiter for the script

      3.2.2 Execution: 
     java -cp "$HBN_HOME/*"  org.hibernate.tool.hbm2ddl.SchemaExport  
     --create  $PROJECT_HOME/src/java/org/softlogic/blog/model/*.hbm.xml

Fig.11. Command line execution of the Hibernate tool’s SchemaExport as seen on Linux.

     3.3.   Running the SchemaExport from Apache ANT build scripts
     The Ant script, being the most powerful java code-administration tool, is essentially an xml file that contains the activities to be carried on a java project during build and deployment time . It is also sometimes used to "set up" the various dependencies a project have before the “first-run” of the project. 

     In our case, on first-run  we want our database created.
     Just embed the code below, which you can customise, in the build.xml file (or Netbeansbuild-impl.xml which would have its contents loaded into the build.xml file at compile time).The build script is located on the root of your project folder as captured below.

Fig.12. compilation build file as seen in the project folder

     Modify project build script by embedding another build target node for schemaexport as shown below
<target name="schemaexport">
         <taskdef name="schemaexport" classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
       <schemaexport config="hibernate.cfg.xml"
       <fileset dir="src">
            <include name="**/*.hbm.xml"/>

Content of build.xml file.

Fig.13. config snippet from ant build file

Perform a compilation of the project to have the schemaexport performed.Refresh the database to confirm new table additions



4.0 Legend
    JPA=Java Persistnce Application Programmer Interface 
    ORM=Object Relational Mapping
    DDL=Data Definition Language 

   5.0 References 

  6.0 Dont get yourself bothered to work hard in Life;work smart J