📜 ⬆️ ⬇️

Reverse engineering database schema using Ant and Hibernate Tools

Often, Hibernate programmers have a task to initially configure XML mapping and create POJO classes based on a schema from an existing database.

Undoubtedly, the best way to solve the problem, both in terms of understanding the structure of the base, and in terms of the purity of the code, will be a manual description of classes and mappings.
But when the scheme of the base is of a decent scale, I really want to automate this process ... Or at least create skeletons of POJO classes and XML files that can be manually adjusted later.
To automate the process (and not only), there is the Hibernate Tools package, which allows you to describe tasks for reversing the schema of an existing database into the Hibernate entity files, using the capabilities of the Java Ant application build tool.

In the popular Eclipse and NetBeans development environment , there are wizards to simplify the Hibernate Tools configuration process, but we will not use them (I use NetBeans , but the built-in Hibernate wizard disappointed me with the lack of a flexible configuration of reverse, I didn’t explore the capabilities of Eclipse wizards, but I guess that they are not much different from NetBeans ...). So, we choose the hardcore generation path through Ant-scripts.

We are faced with the task of generating the skeletons of POJO classes and XML mappings for a set of certain Hibernate entities from tables of an existing database.
')
At once I will make a reservation that the article does not go deep into the details of the technologies under consideration and, in fact, is a recipe for solving a specific task.

To demonstrate the flexibility of the configuration, we will change the standard naming strategy of the Hibernate classes from the database table names to our own. The reason for abandoning the standard reverse strategy is that often the names of tables in the database are in the form of plural words for the names of the entities implemented by the tables. When using the standard naming strategy in such a case, the classes will have uninformative names.
Examples:
CUSTOMER, CUSTOMERS;
- ACCOUNT, ACCOUNTS;
- USER_TYPE, USER_TYPES...


The result of the reverse with the default naming strategy for such a scheme will be the following classes:
CUSTOMERS -> class Customers;
ACCOUNTS -> class Accounts;
USER_TYPES -> class UserTypes...

As a result, it will not be easy to understand operations with data objects of entities in Java code - you must admit, it is difficult to guess what the Customers class method returns
Set getAccountses ( ) ;

And in general, operating with single objects of classes with names in the plural is not very convenient.

To solve this problem, you can use your naming strategy, creating new classes and overriding methods of existing strategies.
Consider the source:
import org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy ;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategy ;
import org.hibernate.cfg.reveng.TableIdentifier ;

public class MyNamingStrategy extends DelegatingReverseEngineeringStrategy {

/ *
* @param delegate {@link org.hibernate.cfg.reveng.ReverseEngineeringStrategy}
* /
public MyNamingStrategy ( ReverseEngineeringStrategy delegate ) {
super ( delegate ) ;
}

@ Override
public String tableToClassName ( TableIdentifier tableIdentifier ) {
String tableName = super . tableToClassName ( tableIdentifier ) ;
if ( tableName. endsWith ( "ses" ) ) {
tableName = tableName. substring ( 0 , tableName. length ( ) - 2 ) ;
} else if ( tableName. endsWith ( "s" ) ) {
tableName = tableName. substring ( 0 , tableName. length ( ) - 1 ) ;
}
return tableName ;
}
}

Here we override the tableToClassName ( ) method, in the body of which, we first get the standard class name for this table, then cut off the plural suffix. After applying this strategy in the reverse process, the names of classes and methods in Hibernate entities will more clearly reflect the meaning of the schema entities.

We turn to the final part of the generation of files Hibernate-entities.
Perform the following sequence of actions:

1. Compile the above class as a java-library.

2. We describe the reveng.xml file in which we indicate the entities selected for reverse engineering:
<? xml version = "1.0" encoding = "UTF-8" ?>
<! DOCTYPE hibernate-reverse-engineering PUBLIC "- // Hibernate / Hibernate Reverse Engineering DTD 3.0 // EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd">
<hibernate-reverse-engineering >
<schema-selection match-schema = "DBSCHEMA" />
<table-filter match-name = "CUSTOMERS" />
<table-filter match-name = "USERS" />
<table-filter match-name = "USER_TYPES" />
<table-filter match-name = "ACCOUNTS" />
</ hibernate-reverse-engineering >

3. Then create a build.xml - Ant-script to generate files based on the following template:
<? xml version = "1.0" encoding = "UTF-8" ?>
<project name = "reverse" default = "all" basedir = "." >

<path id = "project.classpath" >
<! - Path to the Hibernate and Hibernate Tools Libraries ->
<fileset dir = "../lib" >
<include name = "** / *. jar" />
</ fileset >
<! - Library path with our naming strategy ->
<fileset dir = "../dist" >
<include name = "** / *. jar" />
</ fileset >
</ path >


<taskdef name = "hibernatetool"
classname = "org.hibernate.tool.ant.HibernateToolTask"
classpathref = "project.classpath" />

<target name = "all" >
<hibernatetool >
<jdbcconfiguration
configurationfile = "hibernate.cfg.xml"
packagename = "hibernate.entities"
revengfile = "reveng.xml"
reversestrategy = "MyNamingStrategy" />
<hbm2hbmxml destdir = "." />
<hbm2java destdir = "." />
</ hibernatetool >
</ target >
</ project >

The path tag here defines the paths to the classes used in the generation (Hibernate, Hibernate Tools, our MyNamingStrategy). The tags hbm2hbmxml and hbm2java instruct the tools to create XML mapping and POJO classes, respectively. The paths for the generated files can be controlled using the destdir arguments of the corresponding tags.
The hbm2java tag has two important, but optional attributes:Also worth mentioning is the jdbcconfiguration tag arguments :4. Run Ant in a directory with build.xml and enjoy the process:
...>ant
Buildfile: build.xml

all:
[hibernatetool] Executing Hibernate Tool with a JDBC Configuration (for reverse engineering)
[hibernatetool] 1. task: hbm2hbmxml (Generates a set of hbm.xml files)
[hibernatetool] 2. task: hbm2java (Generates a set of .java files)

BUILD SUCCESSFUL
Total time: 9 seconds


As a result, in the specified directories we get a set of generated POJO classes and XML mappings with the “correct” names.

Source: https://habr.com/ru/post/60298/


All Articles