Automating Hibernating Mapping and Queries For Java Web Development

Java Development News:

Automating Hibernating Mapping and Queries For Java Web Development

By Chris Keene

01 May 2009 | TheServerSide.com

Hibernate is a powerful library for mapping relational data to Java classes. Setting up the Hibernate object-relational mapping and writing basic Hibernate queries to create, read, update and delete table data can be tedious and time consuming. This paper introduces WaveMaker as a way to automate the generation of Hibernate classes, including support for managing related tables, creating custom HQL queries and defining custom Hibernate views.

The WaveMaker studio is a free and open source software tool for building web applications. WaveMaker imports a database schema and automatically generates corresponding Hibernate classes. With WaveMaker, the developer can also modify the schema, define views and create queries from a visual editor. Once the mapping, views and queries are defined, WaveMaker generates Eclipse-ready project files or WAR files that can be deployed onto any Java server. Wavemaker also provides visual tools to connect Hibernate classes to an Ajax front end.

Hibernate And Web Development The Hard Way - Hand Coding The Hibernate "Stack"

With Hibernate, a developer can link complex relational schemas to equally complex Java objects, complete with relationships, queries and transactions. Yet all this power comes at a cost.

Hibernate has a steep learning curve that requires understanding a whole new query language (Hibernate Query Language, or HQL), a special format for specifying data mappings (hbm.xml files) and another format for connecting to databases ( cfg.xml files).   

In addition, working with Hibernate requires a good deal of Java programming to create Java classes that implement methods to get and set attribute and relationship value. Each HQL query also requires its own Java class.

For Java developers who are building web applications, getting the server-side Hibernate infrastructure working is only the start. The developer still needs to use a service such as JSON RPC to serialize Java data into a JSON format and pass it over to the client. Similarly, the client framework needs a way to invoke Hibernate methods on the server and pass the necessary JSON structures back and forth. 

Hibernate and Web Development The Easy Way - Automated Generation of Hibernate Files

Given a particular database schema, almost all of the code required to create the Hibernate mapping to Java classes can be automated. Similarly, given an HQL query and a database schema, the Java classes and xml files to implement the query can be generated. Finally, given a set of Java classes, creating a set of JSON RPCs to ferry data back and forth between a Javascript client and a Java server can be automated.

WaveMaker is an open source product that completely automates the generation of Hibernate files to access a database as well as managing JSON communication between a Javascript client and a Java server. With WaveMaker, creating an end-to-end Java application with an web browser client and a database server is largely automated. The steps to using WaveMaker are:

  • Step 1. Import existing schema or create schema: the WaveMaker data model editor can import or create schemas for all major databases, including MySQL, PostgreSQL, Oracle, DB/2 and MS SQL Server. HSQLDB is bundled with WaveMaker as a built-in database. All Hibernate Java classes and xml mapping files are created automatically at this point. 
  • Step 2. Create custom queries: the WaveMaker HQL query editor allows you to create and debug Hibernate HQL queries on the fly. The developer specifies the query and any input parameters, then can test the query by providing the required parameters and getting the results.
  • Step 3. Add custom Java: add Java libraries or Java classes to WaveMaker using Eclipse or any other standard Java IDE.
  • Step 4. Create Web GUI using drag and drop tool: use WaveMaker's browser-based studio to drag and drop Ajax widgets onto a canvas and connect them to Hibernate methods via a visual binding editor. You can run these applications dynamically using WaveMaker's built-in Tomcat server.
  • Step 5. Deploy application to any Java server: with WaveMaker's live deployment capability, create a WAR file and deploy it to any Java server, including Tomcat, JBoss, Glassfish, WebSphere and WebLogic.

 

 

 

The following table compares the steps required to build a web application using Java and Hibernate by hand versus automating the same task using WaveMaker.

 

Task

Hand coding in Java

Automated with WaveMaker

Identify existing data schema or create new one

Use DB admin tool like SQLYog

Use WaveMaker to import or create new schema

Create Java classes for each table in schema

By hand for each table

Automated

Define Hibernate mapping file for each Java class

By hand for each table

Automated

Build Hibernate configuration file for DB login

By hand for each project

Automated

Build Ant file to compile project

By hand for each project

Automated

Write Java startup class for Hibernate

By hand for each project

Automated

Write and test Hibernate HQL queries

Compile, link, curse, fix, compile, link, ...

WaveMaker has a built-in HQL editor that allows you to write and test queries on the fly

Create Java classes for each Hibernate query

By hand for each query return type

Automated

Create JSON RPC mechanism to move data between Java server and Javascript client

By hand for each class and query return type

Automated

Write Javascript to display and edit data with AJAX class library such as Dojo

By hand for each widget

Visual, drag and drop studio connects Dojo widgets to Javascript services that invoke Hibernate methods.

WaveMaker can be downloaded at www.wavemaker.com or access the cloud version at www.wavemaker.com/cloud.

Hibernate Code Generation Example For Simple Database

This shows using WaveMaker to import a database and create all required Hibernate Files.

Using WaveMaker To Generate Hibernate Files

The following screenshot shows the database import screen for WaveMaker. Note that you can select your database from a drop-down list (this example uses WaveMaker's built in HSQLDB database). You can also create a new database using the data model editor.

 

 

 

After entering the database login information and pressing the Import button, WaveMaker imports the database, creates all necessary Hibernate files, and displays the schema in the data model editor. Column and relationship information for each table are displayed in grids.

 

 

 

Once the database is imported, you can go to the Hibernate file directory to see all the files created automatically by WaveMaker. If you are a do it yourself kind of person, you can simply pick up these files and drop them into whatever Java project you like.

 

 

 

WaveMaker also includes a Hibernate query editor and HQL debugging tool. This shows an HQL query with an associated parameter. At the bottom of the screen you can see the results from running the query.

 

 

 

Once you have defined your data model, you are ready to build an application. WaveMaker automatically creates a business data widget for each table in your database. Simply drag the data widget onto the canvas to automatically create a CRUD application. This shows the business data widget for the Customer table dragged onto the canvas. Note that you can see live data even within the design studio. Press the run button to perform a test run of your new web application using the built-in Tomcat database.

 

 

 

Files Generated by WaveMaker

This shows the files created by WaveMaker to implement an object-relational mapping between 

Database schema

Here is a sample database schema for HSQLDB (which is bundled with the WaveMaker download)

 CREATE TABLE CUSTOMER(CUSTID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY, NAME VARCHAR(50), STATE VARCHAR(2), PARENTCO INTEGER DEFAULT NULL, CONSTRAINT SUBSIDIARIESFKEY FOREIGN KEY(PARENTCO) REFERENCES CUSTOMER(CUSTID)) CREATE TABLE PURCHASE(ORDERID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY, ORDERDATE DATE NOT NULL, ORDERVALUE INTEGER DEFAULT NULL, CUSTOMERNUMBER INTEGER NOT NULL, CONSTRAINT ORDERSFKEY FOREIGN KEY(CUSTOMERNUMBER) REFERENCES CUSTOMER(CUSTID))

Generated Files

Upon importing this data schema into WaveMaker using the database import feature, WaveMaker generates the following files (the directory for the generated code is projectnameservicesdbnamesrccomdata):

  • Dbname.java - implements Hibernate data service manager
  • Customer.java - implements Customer class 
  • Customer.hbm.xml - defines mapping between Customer Class and CUSTOMER table in HSQLDB
  • Purchase.java - implements Customer class
  • Purchase.hbm.xml - defines mapping between Customer Class and CUSTOMER table in HSQLDB

Customer.java File

Here is the generated Customer.java file created by WaveMaker.

 package com.data; import java.util.HashSet; import java.util.Set; /** * gurudb.Customer * 04/23/2009 11:58:43 */ public class Customer { private Integer custid; private com.data.Customer customer; private String name; private String state; private Set<com.data.Customer> customers = new HashSet<com.data.Customer>(); private Set<com.data.Purchase> purchases = new HashSet<com.data.Purchase>(); public Customer() { } public Customer(Integer custid, String name, String state) { this.custid = custid; this.name = name; this.state = state; } public Customer(Integer custid, com.data.Customer customer, String name, String state, Set<com.data.Customer> customers, Set<com.data.Purchase> purchases) { this.custid = custid; this.customer = customer; this.name = name; this.state = state; this.customers = customers; this.purchases = purchases; } public Integer getCustid() { return custid; } public void setCustid(Integer custid) { this.custid = custid; } public com.data.Customer getCustomer() { return customer; } public void setCustomer(com.data.Customer customer) { this.customer = customer; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getState() { return state; } public void setState(String state) { this.state = state; } public Set<com.data.Customer> getCustomers() { return customers; } public void setCustomers(Set<com.data.Customer> customers) { this.customers = customers; } public Set<com.data.Purchase> getPurchases() { return purchases; } public void setPurchases(Set<com.data.Purchase> purchases) { this.purchases = purchases; } }

Customer.hbm.xml File

Here is the generated Customer.hbm.xml file created by WaveMaker.

 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.data.Customer" table="CUSTOMER" schema="PUBLIC" dynamic-insert="false" dynamic-update="false"> <id name="custid" type="integer"> <column name="CUSTID"/> <generator class="identity"/> </id> <property name="name" type="string"> <column name="NAME" length="50"/> </property> <property name="state" type="string"> <column name="STATE" length="2"/> </property> <many-to-one name="customer" class="com.data.Customer" cascade="save-update"> <column name="PARENTCO"/> </many-to-one> <set name="customers" inverse="true"> <key> <column name="PARENTCO"/> </key> <one-to-many class="com.data.Customer"/> </set> <set name="purchases" inverse="true"> <key> <column name="CUSTOMERNUMBER" not-null="true"/> </key> <one-to-many class="com.data.Purchase"/> </set> </class> </hibernate-mapping>

HQL Queries

For each HQL query that returns something other than all columnst (e.g., SELECT *), WaveMaker creates a query.hbm.xml file and a queryNameType.java file. Here are the files created for a sample HQL query:

 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <meta attribute="@design.default-queries"/> <query name="selectInner"> SELECT cust.name AS name, purch.orderdate AS order_date, purch.ordervalue AS order_value FROM Customer AS cust INNER JOIN cust.purchases AS purch </query> </hibernate-mapping> /** * Generated for query "selectInner" on 04/23/2009 19:23:38 */ public class SelectInnerRtnType { private String name; private Date order_date; private Integer order_value; public SelectInnerRtnType() { } public SelectInnerRtnType(String name, Date order_date, Integer order_value) { this.name = name; this.order_date = order_date; this.order_value = order_value; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getOrder_date() { return order_date; } public void setOrder_date(Date order_date) { this.order_date = order_date; } public Integer getOrder_value() { return order_value; } public void setOrder_value(Integer order_value) { this.order_value = order_value; } }

Author Bio

Chris Keene is the CEO of WaveMaker (www.wavemaker.com). WaveMaker makes Java web development easier and faster. Chris was previously the CEO of Persistence software, the company that pioneered object-relational mapping and caching. His blog is www.keeneview.com.

Related Resources