devstory

Générer des tables à partir de classes Entity dans Hibernate

  1. L'objectif de ce document
  2. Créer le projet Maven et déclarer des bibliothèques
  3. Des classes Entity
  4. hibernate-xxx.cfg.xml
  5. Générer des tableaux à partir des Entity

1. L'objectif de ce document

Ce document est basé sur:
  • Hibernate 5.2.2.Final

  • Eclipse 4.6 (MARS)

Dans ce document, je vous guiderai pour créer des tableaux (Oracle, MySQL, SQL Server, ..) à partir des classes Entity. Les tableaux créés seront remplis de contraintes telles que désignées par les classes Entity.
Notez que Hibernate est né afin de travailler avec n'importe quelle base de données. Cela signifie que lors que vous changez une autre database vous ne devez pas changez le code du programme. Mais vous devez créez des tables dans database. Hibernate vous fournit de créer des tables à partir des classes Entity.
Le post est la prochaine partie de "Tutoriel d'utilisation du Hibernate pour des nuls", que vous pouvez lire ici:

2. Créer le projet Maven et déclarer des bibliothèques

Dans pom.xml je déclare la bibliothèque Hibernate 5, et des bibliothèques JDBC pour différents types de Database tels que Oracle, MySQLSQL Server.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.o7planning</groupId>
  <artifactId>HibernateGenerateTables</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>HibernateGenerateTables</name>
  <url>http://maven.apache.org</url>


   <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>


   <repositories>
       <!-- Repository for ORACLE JDBC Driver -->
       <repository>
           <id>codelds</id>
           <url>https://code.lds.org/nexus/content/groups/main-repo</url>
       </repository>
   </repositories>
 
 
   <dependencies>


       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>3.8.1</version>
           <scope>test</scope>
       </dependency>

       <!-- Hibernate Core -->
       <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
       <dependency>
           <groupId>org.hibernate</groupId>
           <artifactId>hibernate-core</artifactId>
           <version>5.2.2.Final</version>
       </dependency>


       <!-- MySQL JDBC driver -->
       <!-- http://mvnrepository.com/artifact/mysql/mysql-connector-java -->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.34</version>
       </dependency>

       <!-- Oracle JDBC driver -->
       <dependency>
           <groupId>com.oracle</groupId>
           <artifactId>ojdbc6</artifactId>
           <version>11.2.0.3</version>
       </dependency>

       <!-- SQLServer JDBC driver (JTDS) -->
       <!-- http://mvnrepository.com/artifact/net.sourceforge.jtds/jtds -->
       <dependency>
           <groupId>net.sourceforge.jtds</groupId>
           <artifactId>jtds</artifactId>
           <version>1.3.1</version>
       </dependency>

   </dependencies>
 
</project>

3. Des classes Entity

Nous créons la classe Entity. Chaque Entity décrit une tavle dans DB. Attendez une minute, n'en parlez rien dans ces classes.
  • Department - le département
  • Employee - l'employé
  • SalaryGrade - le niveau du salaire
  • Timekeeper - Le chonométreur, contrôleur l'entrée et la sortie des employés.
Department.java
package org.o7planning.tutorial.hibernate.entities;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name = "DEPARTMENT",
  uniqueConstraints = { @UniqueConstraint(columnNames = { "DEPT_NO" }) })
public class Department {

private Integer deptId;
private String deptNo;

private String deptName;
private String location;
private Set<Employee> employees = new HashSet<Employee>(0);

public Department() {
}

public Department(Integer deptId, String deptName, String location) {
   this.deptId = deptId;
   this.deptNo = "D" + this.deptId;
   this.deptName = deptName;
   this.location = location;
}

@Id
@Column(name = "DEPT_ID")
public Integer getDeptId() {
   return deptId;
}

public void setDeptId(Integer deptId) {
   this.deptId = deptId;
}

@Column(name = "DEPT_NO", length = 20, nullable = false)
public String getDeptNo() {
   return deptNo;
}

public void setDeptNo(String deptNo) {
   this.deptNo = deptNo;
}

@Column(name = "DEPT_NAME", nullable = false)
public String getDeptName() {
   return deptName;
}

public void setDeptName(String deptName) {
   this.deptName = deptName;
}

@Column(name = "LOCATION")
public String getLocation() {
   return location;
}

public void setLocation(String location) {
   this.location = location;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "department")
public Set<Employee> getEmployees() {
   return employees;
}

public void setEmployees(Set<Employee> employees) {
   this.employees = employees;
}
}
Employee.java
package org.o7planning.tutorial.hibernate.entities;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name = "EMPLOYEE",
   uniqueConstraints = { @UniqueConstraint(columnNames = { "EMP_NO" }) })
public class Employee {
private Long empId;
private String empNo;

private String empName;
private String job;
private Employee manager;
private Date hideDate;
private Float salary;
private byte[] image;

private Department department;
private Set<Employee> employees = new HashSet<Employee>(0);

public Employee() {
}

public Employee(Long empId, String empName, String job, Employee manager,
        Date hideDate, Float salary, Float comm, Department department) {
    this.empId = empId;
    this.empNo = "E" + this.empId;
    this.empName = empName;
    this.job = job;
    this.manager = manager;
    this.hideDate = hideDate;
    this.salary = salary;
    this.department = department;
}

@Id
@Column(name = "EMP_ID")
public Long getEmpId() {
    return empId;
}

public void setEmpId(Long empId) {
    this.empId = empId;
}

@Column(name = "EMP_NO", length = 20, nullable = false)
public String getEmpNo() {
    return empNo;
}

public void setEmpNo(String empNo) {
    this.empNo = empNo;
}

@Column(name = "EMP_NAME", length = 50, nullable = false)
public String getEmpName() {
    return empName;
}

public void setEmpName(String empName) {
    this.empName = empName;
}

@Column(name = "JOB", length = 30, nullable = false)
public String getJob() {
    return job;
}

public void setJob(String job) {
    this.job = job;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MNG_ID")
public Employee getManager() {
    return manager;
}

public void setManager(Employee manager) {
    this.manager = manager;
}

@Column(name = "HIRE_DATE", nullable = false)
@Temporal(TemporalType.DATE)
public Date getHideDate() {
    return hideDate;
}

public void setHideDate(Date hideDate) {
    this.hideDate = hideDate;
}

@Column(name = "SALARY", nullable = false)
public Float getSalary() {
    return salary;
}

public void setSalary(Float salary) {
    this.salary = salary;
}

@Column(name = "IMAGE", length = 1111111, nullable = true)
@Lob
public byte[] getImage() {
    return image;
}

public void setImage(byte[] image) {
    this.image = image;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DEPT_ID", nullable = false)
public Department getDepartment() {
    return department;
}

public void setDepartment(Department department) {
    this.department = department;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "empId")
public Set<Employee> getEmployees() {
    return employees;
}

public void setEmployees(Set<Employee> employees) {
    this.employees = employees;
}

}
SalaryGrade.java
package org.o7planning.tutorial.hibernate.entities;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "SALARY_GRADE")
public class SalaryGrade {
 private Integer grade;
 private Float lowSalary;
 private Float highSalary;

 public SalaryGrade() {
 }

 public SalaryGrade(Integer grade, Float lowSalary, Float highSalary) {
     this.grade = grade;
     this.lowSalary = lowSalary;
     this.highSalary = highSalary;
 }

 @Id
 @Column(name = "GRADE")
 public Integer getGrade() {
     return grade;
 }

 public void setGrade(Integer grade) {
     this.grade = grade;
 }

 @Column(name = "LOW_SALARY", nullable = false)
 public Float getLowSalary() {
     return lowSalary;
 }

 public void setLowSalary(Float lowSalary) {
     this.lowSalary = lowSalary;
 }

 @Column(name = "HIGH_SALARY", nullable = false)
 public Float getHighSalary() {
     return highSalary;
 }

 public void setHighSalary(Float highSalary) {
     this.highSalary = highSalary;
 }
}
Timekeeper.java
package org.o7planning.tutorial.hibernate.entities;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "TIMEKEEPER")
public class Timekeeper {
  public static final char IN = 'I';
  public static final char OUT = 'O';

  private String timekeeperId;

  private Date dateTime;

  private Employee employee;

  // 'I' or 'O'
  private char inOut;

  @Id
  @GeneratedValue(generator = "uuid")
  @GenericGenerator(name = "uuid", strategy = "uuid2")
  @Column(name = "Timekeeper_Id", length = 36)
  public String getTimekeeperId() {
      return timekeeperId;
  }

  public void setTimekeeperId(String timekeeperId) {
      this.timekeeperId = timekeeperId;
  }

  @Column(name = "Date_Time", nullable = false)
  @Temporal(TemporalType.TIMESTAMP)
  public Date getDateTime() {
      return dateTime;
  }

  public void setDateTime(Date dateTime) {
      this.dateTime = dateTime;
  }

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "EMP_ID", nullable = false)
  public Employee getEmployee() {
      return employee;
  }

  public void setEmployee(Employee employee) {
      this.employee = employee;
  }

  @Column(name = "In_Out", nullable = false, length = 1)
  public char getInOut() {
      return inOut;
  }

  public void setInOut(char inOut) {
      this.inOut = inOut;
  }

}

4. hibernate-xxx.cfg.xml

Pour créer des tables, vous avez besoin d'un fichier de configuration d'une base de données database (hibernate-<datatype>.cfg.xml) et des classes Entity.
hibernate-oracle.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>

       <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
       <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
       <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:db12c</property>
       <property name="hibernate.connection.username">simplehr2</property>
       <property name="hibernate.connection.password">12345</property>
       <property name="hibernate.show_sql">true</property>
       <property name="hibernate.connection.release_mode">auto</property>
       <property name="current_session_context_class">thread</property>
       <property name="hibernate.connection.autoReconnect">true</property>


       <mapping class="org.o7planning.tutorial.hibernate.entities.Department" />
       <mapping class="org.o7planning.tutorial.hibernate.entities.Employee" />
       <mapping class="org.o7planning.tutorial.hibernate.entities.SalaryGrade" />
       <mapping class="org.o7planning.tutorial.hibernate.entities.Timekeeper" />

   </session-factory>
 
</hibernate-configuration>
hibernate-mysql.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
<session-factory>
  <!-- Database connection settings -->
  <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="connection.url">jdbc:mysql://tran-vmware:3306/simplehr?serverTimezone=UTC</property>
  <property name="connection.username">root</property>
  <property name="connection.password">1234</property>
 
  <!-- JDBC connection pool (use the built-in) -->
  <property name="connection.pool_size">1</property>
 
  <!-- SQL dialect -->
  <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
 
  <!-- Enable Hibernate's automatic session context management -->
  <property name="current_session_context_class">thread</property>
 
  <!-- Disable the second-level cache  -->
  <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
 
  <!-- Echo all executed SQL to stdout -->
  <property name="show_sql">true</property>
 
   <mapping class="org.o7planning.tutorial.hibernate.entities.Department" />
   <mapping class="org.o7planning.tutorial.hibernate.entities.Employee" />
   <mapping class="org.o7planning.tutorial.hibernate.entities.SalaryGrade" />
   <mapping class="org.o7planning.tutorial.hibernate.entities.Timekeeper" />
 
</session-factory>

</hibernate-configuration>
hibernate-sqlserver.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
      "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
      "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
 <session-factory>
   <!-- Database connection settings -->
   <property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
   <property name="connection.url">jdbc:jtds:sqlserver://localhost:1433/simplehr;instance=SQLEXPRESS</property>
   <property name="connection.username">sa</property>
   <property name="connection.password">1234</property>
 
   <!-- JDBC connection pool (use the built-in) -->
   <property name="connection.pool_size">1</property>
 
   <!-- SQL dialect -->
   <property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
 
   <!-- Enable Hibernate's automatic session context management -->
   <property name="current_session_context_class">thread</property>
 
   <!-- Disable the second-level cache  -->
   <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
 
   <!-- Echo all executed SQL to stdout -->
   <property name="show_sql">true</property>
 
    <mapping class="org.o7planning.tutorial.hibernate.entities.Department" />
    <mapping class="org.o7planning.tutorial.hibernate.entities.Employee" />
    <mapping class="org.o7planning.tutorial.hibernate.entities.SalaryGrade" />
    <mapping class="org.o7planning.tutorial.hibernate.entities.Timekeeper" />
 
</session-factory>

</hibernate-configuration>
Assurez- vous que vous avez créé un Schema vide. (La database n'a aucune tables). Par exemple, avec Oracle j'ai créé un nouveau Schema baptisé simplehr2.
-- ORACLE
Create user simplehr2 identified by 12345;
grant dba to simplehr2;

5. Générer des tableaux à partir des Entity

SchemaGeneratorDemo.java
package org.o7planning.generatetables;

import java.io.File;
import java.util.EnumSet;

import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;

// Hibernate 5.
public class SchemaGeneratorDemo {

   public static final String SCRIPT_FILE = "exportScript.sql";

   private static SchemaExport getSchemaExport() {

       SchemaExport export = new SchemaExport();
       // Script file.
       File outputFile = new File(SCRIPT_FILE);
       String outputFilePath = outputFile.getAbsolutePath();

       System.out.println("Export file: " + outputFilePath);

       export.setDelimiter(";");
       export.setOutputFile(outputFilePath);
       
       // No Stop if Error
       export.setHaltOnError(false);
       //
       return export;
   }

   public static void dropDataBase(SchemaExport export, Metadata metadata) {
       // TargetType.DATABASE - Execute on Databse
       // TargetType.SCRIPT - Write Script file.
       // TargetType.STDOUT - Write log to Console.
       EnumSet<TargetType> targetTypes = EnumSet.of(TargetType.DATABASE, TargetType.SCRIPT, TargetType.STDOUT);

       export.drop(targetTypes, metadata);
   }

   public static void createDataBase(SchemaExport export, Metadata metadata) {
       // TargetType.DATABASE - Execute on Databse
       // TargetType.SCRIPT - Write Script file.
       // TargetType.STDOUT - Write log to Console.
 
       EnumSet<TargetType> targetTypes = EnumSet.of(TargetType.DATABASE, TargetType.SCRIPT, TargetType.STDOUT);

       SchemaExport.Action action = SchemaExport.Action.CREATE;
       //
       export.execute(targetTypes, action, metadata);

       System.out.println("Export OK");

   }

   public static void main(String[] args) {

       // Using Oracle Database.
 
       String configFileName = "hibernate-oracle.cfg.xml";

       // Create the ServiceRegistry from hibernate-xxx.cfg.xml
       ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()//
               .configure(configFileName).build();

       // Create a metadata sources using the specified service registry.
       Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build();

       SchemaExport export = getSchemaExport();

       System.out.println("Drop Database...");
       // Drop Database
       dropDataBase(export, metadata);

       System.out.println("Create Database...");
       // Create tables
       createDataBase(export, metadata);
   }
   
}
Exécution de l'exemple:
Voir des fichiers Script: