RSS

Using Hibernate tools through Maven and Ant

07 May

Hibernate Tools is a toolset for Hibernate3 implemented as an integrated suite of Eclipse plugins, together with a unified Ant task for integration into the build cycle. Hibernate Tools is a core component of JBoss Tools and hence also part of JBoss Developer Studio.

The previous paragraph is the definition of Hibernate tools that you can find in the Hibernate official webpage. This post is going to show you how to generate your domain Java classes from the database schema using 3 different perspectives:

Using the integrated Hibernate tools plugin in Eclips.

Installation and some explanation.

All you have to do is install Hibernate tools from the updated JBoss site, so that open your Eclipse or STS IDE and click Help -> Install New Software. Once there you have to add a new available site. The last version of the Jboss site can be downloaded from http://download.jboss.org/jbosstools/updates/stable/helios/ .

Once you have done this you type Hibernate tools and there it is. Select Hibernate tools and proceed with the instalation.

After you have restart Eclipse, you notice that a new icon for Hibernate tools has been added to the tool bar

There is a codeGeneration configuration create we can see in the imagen above. But before executing that configuration we have to take some steps before.

First of all we create a simple Java project (HIbernateToolsPluginExample). If we want to use the code generation that Hibernate gives us we have to create some files to let know Hibernate tools where our database schema is. So we select File -> New -> Other and type Hibernate. We should see somethig like this:

hibernate wizard

There four different options:
  • Hibernate configuration file (cfg.xml). This file saves information about our database configuration (jdbc url, user, password, driver, hibernate dialect and so on). More information about this file can be found here.
  • Hibernate Reverse Engineering File (reveng.xml). This file contains the information about your database tables. Besides, you can indicate how your database types are going to map to Java types. This file is generating using the Hibernate configuration file.
  • Hibernate console configuration. A configuration we can create and launch after we have an Hibernate configuration file.
  • Hibernate Mapping file (hbm.xml). A database table a mapping file, that’s simple.

Generating the code.

We are going to generate java classes from a MySql database, so here it goes:

  • Step 1: creating an HIbernate configuration file.
    From the previous menu we have to select, guess what …, yeah Hibernateconfiguration file. Select the folder where you want to save this file and next.hibernate config xml file
    In the next form we need to set our database configuration. Notice you can create a new console configuration from here.
    hibernate database configuration

    We have checked create a new console configuration so a new screen has showed to us.

    hibernate console configuration

    Here we have a lot of things to configure. For simplicity all we are going to do is select a previously created connection (mySql in my case) to our database. If we select the option tab we can see a Naming strategy field. We are not going to explain this field yet, but it is important in orden to adapt Hibernate tools to our needings.

    hibernate console configuration

    Our hibernate.cfg.xml should look like this.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
    		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    		"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
    	<session-factory>
    		<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
    		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    		<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/test</property>
    		<property name="hibernate.connection.username">root</property>
    		<property name="hibernate.default_schema">test</property>
    		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    	</session-factory>
    </hibernate-configuration>
    
  • Step 2: creating an Hibernate Reverse Engineering File.
    This step is going to allow us to decide from which table/s we want to create our Java classes. So we select File -> New -> Other -> Hibernate Reverse Engineering File.
    All we need is select the console configuration created in step 1. Click the refresh button, and if our database connection and our hibernate.cfg.xmlfile is created in a proper way you should see your database tables in the left panel. Include the ones you want to generate Java classes from.hibernate reverse configuration
  • Step 3. Creating a new launch to generate Java code.
    Click in the launch Hibernate Tool generator.hibernate code generation

    Create a new Hibernate Code generation.
    In the main tab you need to select our previous console configuration and our hibernate.reveng.xml file. Here we came across with another naming strategy field and a template field, both of them will be explained later.

    hibernate console configuration
    As we can see in the left top area a error message is show: ‘at least one exporter option must be select’. So click on the exporter tab and select the ones you need.
    hibernate console configuration
    In our case we want to create a domain object, a DAO and an Hibernate mapping file for the car table. Besides that we want to generate our class with annotations and use Java 5 flavour, so we check those options.
    hibernate exporters

The generated files are shown below.
  • The domain object. Car.java
    // default package
    // Generated 08-may-2011 3:04:54 by Hibernate Tools 3.4.0.CR1
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    /**
     * Car generated by hbm2java
     */
    @Entity
    @Table(name = "Car", catalog = "test")
    public class Car implements java.io.Serializable {
    
    	private long carId;
    	private String company;
    	private String model;
    	private Integer price;
    
    	public Car() {
    	}
    
    	public Car(long carId, String company, String model) {
    		this.carId = carId;
    		this.company = company;
    		this.model = model;
    	}
    
    	public Car(long carId, String company, String model, Integer price) {
    		this.carId = carId;
    		this.company = company;
    		this.model = model;
    		this.price = price;
    	}
    
    	@Id
    	@Column(name = "carId", unique = true, nullable = false, precision = 10, scale = 0)
    	public long getCarId() {
    		return this.carId;
    	}
    
    	public void setCarId(long carId) {
    		this.carId = carId;
    	}
    
    	@Column(name = "company", nullable = false, length = 45)
    	public String getCompany() {
    		return this.company;
    	}
    
    	public void setCompany(String company) {
    		this.company = company;
    	}
    
    	@Column(name = "model", nullable = false, length = 45)
    	public String getModel() {
    		return this.model;
    	}
    
    	public void setModel(String model) {
    		this.model = model;
    	}
    
    	@Column(name = "price")
    	public Integer getPrice() {
    		return this.price;
    	}
    
    	public void setPrice(Integer price) {
    		this.price = price;
    	}
    
    }
    
    
  • The DAO Object. CarHome.java
    // default package
    // Generated 08-may-2011 3:04:55 by Hibernate Tools 3.4.0.CR1
    
    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    
    /**
     * Home object for domain model class Car.
     * @see .Car
     * @author Hibernate Tools
     */
    @Stateless
    public class CarHome {
    
    	private static final Log log = LogFactory.getLog(CarHome.class);
    
    	@PersistenceContext
    	private EntityManager entityManager;
    
    	public void persist(Car transientInstance) {
    		log.debug("persisting Car instance");
    		try {
    			entityManager.persist(transientInstance);
    			log.debug("persist successful");
    		} catch (RuntimeException re) {
    			log.error("persist failed", re);
    			throw re;
    		}
    	}
    
    	public void remove(Car persistentInstance) {
    		log.debug("removing Car instance");
    		try {
    			entityManager.remove(persistentInstance);
    			log.debug("remove successful");
    		} catch (RuntimeException re) {
    			log.error("remove failed", re);
    			throw re;
    		}
    	}
    
    	public Car merge(Car detachedInstance) {
    		log.debug("merging Car instance");
    		try {
    			Car result = entityManager.merge(detachedInstance);
    			log.debug("merge successful");
    			return result;
    		} catch (RuntimeException re) {
    			log.error("merge failed", re);
    			throw re;
    		}
    	}
    
    	public Car findById(long id) {
    		log.debug("getting Car instance with id: " + id);
    		try {
    			Car instance = entityManager.find(Car.class, id);
    			log.debug("get successful");
    			return instance;
    		} catch (RuntimeException re) {
    			log.error("get failed", re);
    			throw re;
    		}
    	}
    }
    
    
  • The Hibernate Mapping file. Car.hbm.xml
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 08-may-2011 3:04:54 by Hibernate Tools 3.4.0.CR1 -->
    <hibernate-mapping>
        <class name="Car" table="Car" catalog="test">
            <id name="carId" type="long">
                <column name="carId" precision="10" scale="0" />
                <generator class="assigned" />
            </id>
            <property name="company" type="string">
                <column name="company" length="45" not-null="true" />
            </property>
            <property name="model" type="string">
                <column name="model" length="45" not-null="true" />
            </property>
            <property name="price" type="java.lang.Integer">
                <column name="price" />
            </property>
        </class>
    </hibernate-mapping>
    
    

In order to customize how hibernate tools generate code we can take two different approaches:

  • Naming strategy. Hibernate tools gives us a class called DelegatingReverseEngineeringStrategy. What we have to do is extend that class and override any of the several method we can modify. In our case we have create an Example strategy class and override the columnToPropertyName. As we have seen our car table has a column called ‘carId’. What we want is that change the name of that column in the car java class to id. For that this code has been written.
    package src;
    
    import org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy;
    import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
    import org.hibernate.cfg.reveng.TableIdentifier;
    
    public class ExampleStrategy extends DelegatingReverseEngineeringStrategy {
    
    	 public ExampleStrategy(ReverseEngineeringStrategy delegate) {
    	  super(delegate);
    	 }
    
    	 public String columnToPropertyName(TableIdentifier table, String column) {
    	  if(column.endsWith("Id")) {
    	   return "id";
    	  } else {
    	   return super.columnToPropertyName(table, column);
    	  }
    	 }
    	}
    

    Include in the reveng.strategy field this class and run your Hibernate Code Generation Configuration again. The carId has changed to this.

    	@Id
    	@Column(name = "carId", unique = true, nullable = false, precision = 10, scale = 0)
    	public long getId() {
    		return this.Id;
    	}
    
  • Templates.
    Hibernate tools uses some generic templates (see this) for generating java classes. Theses templates are written with FreeMarker. So in order to override them all you need to do is creating new ones and add them to the template field in the Hibernate code generation screen.

If you wanna know another ways for creating your domain model you can take a look to either
Through the Hibernate 3 Maven plugin or Creating an Ant task.

 
10 comentarios

Publicado por en 7 May, 2011 en Hibernate

 

Etiquetas: , , , , , ,