How to customize Hibernate Reverse Engineering Code Generation
- Details
- Written by Nam Ha Minh
- Last Updated on 17 July 2019   |   Print Email
1.Customize Code Generation by using hibernate.reveng.xml file
When running Hibernate code generation, you can supply an XML file called hibernate.reveng.xml that allows you to control the reverse engineering process in various options: schema selection, type mappings, table filters, columns, primary keys, foreign keys, etc.In the Hibernate Code Generation Configurations dialog, you can provide the hibernate.reveng.xml file by clicking the Setup button, as shown below:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.org/dtd/hibernate-reverse-engineering-3.0.dtd" > <hibernate-reverse-engineering> <table-filter match-catalog="mysales" match-name="user" exclude="true"/> </hibernate-reverse-engineering>You can realize that the Hibernate Reverse Engineering Editor has several tabs that allow you to specify the configurations visually (very convenient for programmers). The following screenshot shows the visual editor for table filters: As you can see, you can use the visual editors for type mappings, table filters and tables & columns. For other configurations, you have to edit the XML code directly (with code suggestion supported).
Schema selection
If the connection returns multiple schemas (in case of MySQL, the database URL has no schema name e.g. jdbc:mysql://localhost:3306/), you can use the <schema-selection> tag to specify which schemas to be processed. For example:<schema-selection match-catalog="sales"/>This processes only the schema name (database name) “sales” in MySQL database. In another RDBMS, you might have to use the match-schema attribute:
<schema-selection match-schema="sales"/>The following statement tells Hibernate Tools to do reverse engineering only on tables that start with “order” in the database “sales”:
<schema-selection match-catalog="sales" match-table="order.*"/>
Type mappings
You can use the <type-mapping> section with <sql-type>tag to specify how JDBC types found in the database should be mapped to Hibernate types in Java. For example, the following XML will generate Java fields of type Long from columns of type INTEGER in the database:<type-mapping> <sql-type jdbc-type="INTEGER" hibernate-type="Long" /> </type-mapping>The generated code would be like this (the result of reverse engineering of the table “Category”):
/** * Category generated by hbm2java */ @Entity @Table(name = "category", catalog = "mysales") public class Category implements java.io.Serializable { private Long categoryId; .... }Note that the value of the jdbc-type attribute must be a type of java.sql.Types. (see SQLType).
Table Filters
The <table-filter>tag lets you specify tables to be excluded or included in the reverse engineering, following some matching rules. For example, the following statement tells Hibernate Tools does not process the table “user” in the database “mysales” during the reverse engineering (exclude = “true”):<table-filter match-catalog="mysales" match-name="user" exclude="true"/>But the following statement processes only the table “user”:
<table-filter match-catalog="mysales" match-name="user" exclude="false"/>The following XML processes tables having prefix “pro” and put the generated model classes under the specified package:
<table-filter match-name="pro.*" exclude="false" package="com.mycompany.products" />
Specific Table Configuration
The <table> tag lets you control at greater details how a table should be reversed engineered: table name, class name, primary column, foreign key column, and individual columns. Here is the syntax of the <table> tag:<table catalog="catalog_name" schema="schema_name" name="table_name" class="ClassName" > <primary-key.../> <column.../> <foreign-key.../> </table>For more details, please consult the Hibernate Tools documentation Controlling reverse engineering.
2. Customize Code Generation by using a Custom Strategy Class
Besides using XML in the hibernate.reveng.xml file, you can also customize the code generation by Java code. This can be done by creating a Java class that implements the ReverseEngineeringStrategyor extends the DelegatingReverseEngineeringStrategyclass (both are in the package org.hibernate.cfg.reveng).It’s recommended to extend the DelegatingReverseEngineeringStrategy class to implement only the relevant methods. For example, let’s see the following custom strategy class:/** Copyright CodeJava.net To Present All rights reserved. */ package net.codejava; import org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy; import org.hibernate.cfg.reveng.ReverseEngineeringStrategy; import org.hibernate.cfg.reveng.TableIdentifier; public class CustomStrategy extends DelegatingReverseEngineeringStrategy { public CustomStrategy(ReverseEngineeringStrategy delegate) { super(delegate); } @Override public String columnToPropertyName(TableIdentifier table, String column) { if (column.endsWith("_id")) { return "id"; } else { return super.columnToPropertyName(table, column); } } @Override public boolean excludeColumn(TableIdentifier table, String columnName) { if (columnName.endsWith("_on")) { return true; } else { return super.excludeColumn(table, columnName); } } @Override public boolean excludeTable(TableIdentifier table) { if (table.getName().startsWith("stat")) { return true; } else { return super.excludeTable(table); } } }As you can see, this class overrides the following methods:
- columnToPropertyName(): specifies how columns should be mapped to property names. In this strategy, we shorten all the column names ending with “_id” to just “id”.
- excludeColumn(): specifies matching rules to exclude columns from being reversed engineering. In this strategy, we exclude all column names ending with “_on”.
- excludeTable(): specifies matching rules to exclude tables from being reversed engineering. In this strategy, we exclude all table names starting with “stat”.
And in the Hibernate Code Generation Configurations dialog, specify fully qualified class name of the strategy class as follows: Click Run to perform the reverse engineering, and then check the generated code in the specified package.NOTE: Using a custom strategy class requires the Hibernate Tools JAR file to be present in the project’s classpath. You can add a dependency in Maven’s POM file, but it requires several dependencies related to Eclipse runtime, which is not necessary. So it’s recommend to add a reference to Hibernate Tools JAR file which can be found in the following path under Eclipse’s installation directory:eclipse\configuration\org.eclipse.osgi\1049\0\.cp\lib\hibernate-tools-5.2.8.Final.jarAs shown below in the Java Build Path section of the project’s Properties screen:And for your reference, the following list contains some methods in the DelegatingReverseEngineeringStrategy class which you can override:
- columnToHibernateTypeName()
- columnToMetaAttributes()
- columnToPropertyName()
- excludeColumn()
- excludeForeignKeyAsCollection()
- excludeForeignKeyAsManytoOne()
- excludeTable()
- foreignKeyToAssociationInfo()
- foreignKeyToCollectionName()
- foreignKeyToEntityName()
- foreignKeyToInverseAssociationInfo()
- foreignKeyToInverseEntityName()
- foreignKeyToManyToManyName()
- tableToClassName()
- tableToCompositeIdName()
- tableToIdentifierPropertyName()
- tableToMetaAttributes()
3. Customize POJO Code Generation using <meta> Tag
What if you want to generate equals(), hashCode(), toString(), your own comments,… or any custom code in the POJO model classes? To do so, you can use the <meta> tag in the Hibernate Reverse Engineering XML file hibernate.reveng.xml. Let’s see some examples.Generate equals() and hashCode() methods:
Add the following <meta> tag inside a <column> tag of a <table> section to specify that the column will be used in the code of equals() and hashCode() methods:<meta attribute="use-in-equals">true</meta>For example, the following XML code tells Hibernate Tools to use the column category_id in the code of equals() and hashCode() methods in the POJO class reversed engineering from the table category:
<table catalog="mysales" name="category"> <column name="category_id"> <meta attribute="use-in-equals">true</meta> </column> </table>And you can see the generated code for equals() and hashCode() in the Category class looks like this:
public boolean equals(Object other) { if ((this == other)) return true; if ((other == null)) return false; if (!(other instanceof net.codejava.hibernate4.Category)) return false; net.codejava.hibernate4.Category castOther = (net.codejava.hibernate4.Category) other; return ((this.getCategoryId() == castOther.getCategoryId()) || (this.getCategoryId() != null && castOther.getCategoryId() != null && this.getCategoryId().equals(castOther.getCategoryId()))); } public int hashCode() { int result = 17; result = 37 * result + (getCategoryId() == null ? 0 : this.getCategoryId().hashCode()); return result; }So to add more columns/properties involved in the equals() and hashCode() calculation, just add relevant <meta> tag like the above example.
Generate toString() method:
Similarly, add the following <meta> tag inside a <column> tag to use the column in toString() method:<meta attribute="use-in-tostring">true</meta>For example:
<table catalog="mysales" name="product"> <column name="name"> <meta attribute="use-in-tostring">true</meta> </column> </table>And the generated code looks like this:
public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(getClass().getName()).append("@").append(Integer.toHexString(hashCode())).append(" ["); buffer.append("name").append("='").append(getName()).append("' "); buffer.append("]"); return buffer.toString(); }
Generate comments for class description and field description:
The following <meta> tag will generate comment for the class description:<table catalog="mysales" name="category"> <meta attribute="class-description"> A category that contains related products. </meta> </table>And the generated code looks like this:
/** * A category that contains related products. * */ @Entity @Table(name = "category", catalog = "mysales") public class Category implements java.io.Serializable { ... }Similarly, specify the following XML to generate comment for a field:
<column name="price"> <meta attribute="field-description"> Price of the product in USD. </meta> </column>
Generate your own code:
The following XML adds extra code that is inserted at the end of the class:<table catalog="mysales" name="product"> <meta attribute="class-code"> private void myMethod(String s) { System.out.println(s); } </meta> </table>And the generated code looks like this:
// The following is extra code specified in the hbm.xml files private void myMethod(String s) { System.out.println(s); } // end of extra code specified in the hbm.xml filesFor more customization, refer to the document Controlling reverse engineeringNOTE: If you want to have total control of code generation, edit the Freemarker Templates (.ftl files) which can be found under the package pojo in Hibernate Tools JAR file.
Other Hibernate Tutorials:
- Java Hibernate Reverse Engineering Tutorial with Eclipse and MySQL
- Java Hibernate JPA Annotations Tutorial for Beginners
- Hibernate Hello World Tutorial for Beginners with Eclipse and MySQL
- Hibernate One-to-One Association on Primary Key Annotations Example
- Hibernate One-to-Many Using Join Table XML Mapping Example
- Hibernate Many-to-Many Association with Extra Columns in Join Table Example
- Hibernate Enum Type Mapping Example
- Hibernate Binary Data and BLOB Mapping Example
- Hibernate Basics - 3 ways to delete an entity from the datastore
- Hibernate Query Language (HQL) Example
Comments
Hmm. I'm not sure. You should look at the official document to know more:
docs.jboss.org/.../reverseengineering.html
is it possible to generate entities in this form?:
@Entity
@Table(name = "category", catalog = "mysales")
public class Category extend BaseEntity implements java.io.Serializable {