Hibernate: ejemplo de tabla por subclase usando un archivo XML

En Tabla por subclase , las tablas de subclase se asignan a la tabla de clase principal por relación de clave principal y clave externa . En una estrategia de tabla por subclase:

  • Para cada clase de jerarquía existe una tabla separada en la base de datos.
  • Al crear las tablas de la base de datos, se requiere una relación de clave externa entre la tabla principal y la tabla secundaria.
  • Para pasar información a la hibernación que aplica el mapeo de tabla por subclase, configuramos la etiqueta <joined-subclass> debajo de la etiqueta <class> del archivo hbm.xml .
  • La columna del discriminador es opcional.

Dado que las tablas de subclase tienen una asociación de clave externa con la tabla de superclase, no habrá columnas duplicadas en la tabla de subclase, excepto una columna que se requiere para mantener la relación entre las tablas principal y de subclase a través de una clave externa .

Ejemplo de estrategia Tabla por subclase (mapeo XML)

Supongamos que tenemos una clase Empleado con subclases como P_Employee y C_Employee. Siguiendo el diagrama de clases y relación de estas clases.

Hierarchy of Classes

Jerarquía de Clases

Tenemos 3 tablas Employee , P_Employee y C_Employee para conservar los datos de la clase. Existe una relación de clave externa entre las tablas de subclase y las tablas de superclase. Por lo tanto, los datos comunes se almacenan en la tabla Empleado y los campos específicos de la subclase se almacenan en las tablas P_Employee y C_Employee .

Creando una tabla de base de datos para persistir clases concretas:

CREAR TABLA `Empleado` (

       `id` BIGINT(20) NO NULO AUTO_INCREMENTO,

      `nombre` VARCHAR(50) NO NULO PREDETERMINADO ‘0’,

      `edad` BIGINT(3) NO NULO PREDETERMINADO ‘0’,

       CLAVE PRIMARIA (`id`)

)

CREAR TABLA `P_Empleado` (

      `id` BIGINT(20) NO NULO AUTO_INCREMENTO,

    `salario` BIGINT(11) NULL DEFAULT NULL,

    CLAVE PRIMARIA (`id`)

    RESTRICCIÓN `ForK_Employee` CLAVE EXTERNA (`id`) REFERENCIAS `Empleado` (`id`)

)

CREAR TABLA `C_Empleado` (

     `id` BIGINT(20) NO NULO AUTO_INCREMENTO,

     `tarifahora` BIGINT(11) NULL DEFAULT NULL,

    `duración` BIGINT(11) NULO PREDETERMINADO NULO,

    CLAVE PRIMARIA (`id`)

    RESTRICCIÓN `ForK_Employee2` CLAVE EXTERNA (`id`) REFERENCIAS `Empleado` (`id`)

)

Estructura del proyecto (IntelliJ IDEA) para mapeo XML:

Creación de las clases Employee, P_Employee y C_Employee para la jerarquía anterior:

A continuación se muestra la implementación del archivo  Employee.java :

Java

package com.exploit.model;
 
public class Employee {
    private int id;
    private String name;
    private int age;
 
    public int getId() { return id; }
 
    public void setId(int id) { this.id = id; }
 
    public String getName() { return name; }
 
    public void setName(String name) { this.name = name; }
 
    public int getAge() { return age; }
 
    public void setAge(int age) { this.age = age; }
}

A continuación se muestra la implementación del archivo P_Employee.java :

Java

package com.exploit.model;
 
public class P_Employee extends Employee {
    private double salary;
 
    public double getSalary() { return salary; }
 
    public void setSalary(double salary)
    {
        this.salary = salary;
    }
}

A continuación se muestra la implementación del archivo C_Employee.java: 

Java

package com.exploit.model;
 
public class C_Employee extends Employee {
    private double hourlyRate;
    private double duration;
 
    public double getDuration() { return duration; }
 
    public void setDuration(double duration)
    {
        this.duration = duration;
    }
 
    public double getHourlyRate() { return hourlyRate; }
 
    public void setHourlyRate(double hourlyRate)
    {
        this.hourlyRate = hourlyRate;
    }
}

Creando el archivo de mapeo para la clase persistente:

A continuación se muestra la implementación del archivo employee.hbm.xml :

XML

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="com.exploit.model">
    <class name="Employee" table="Employee">
        <id name="id" column="Id">
            <generator class="native"></generator>
        </id>
        <property name="name" column="Name"></property>
        <property name="age" column="Age"></property>
 
        <joined-subclass name="com.exploit.model.P_Employee" table="P_Employee">
            <key column="Id"/>
            <property name="salary" column="Salary"></property>
        </joined-subclass>
 
        <joined-subclass name="com.exploit.model.C_Employee" table="C_Employee">
            <key column="Id"/>
            <property name="hourlyRate" column="HourlyRate"></property>
            <property name="duration" column="Duration"></property>
        </joined-subclass>
 
    </class>
 
</hibernate-mapping>

Agregando el mapeo del archivo hbm.xml en el archivo de configuración de hibernación:

A continuación se muestra la implementación del archivo hibernate.cfg.xml :

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 properties -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/javainsimpleway</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
 
        <!-- JDBC connection pool (using the built-in) -->
        <property name="connection.pool_size">1</property>
 
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</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>
 
        <!-- Format the generated Sql -->
        <property name="format_sql">true</property>
 
        <!-- Dont Drop and re-create the database schema on startup,Just update it -->
        <property name="hbm2ddl.auto">update</property>
 
        <mapping resource="com/exploit/mapping/employee.hbm.xml"/>
 
    </session-factory>
 
</hibernate-configuration>

Las siguientes son las dependencias utilizadas en el archivo pom.xml:

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>TablePerSubclassXML</groupId>
    <artifactId>TablePerSubclassXML</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
 
    <name>TablePerSubclassXML</name>
    <url>http://maven.apache.org</url>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
       
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.6.Final</version>
        </dependency>
       
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.5</version>
        </dependency>
       
    </dependencies>
</project>

Creando la clase que almacena el objeto persistente:

A continuación se muestra la implementación del archivo Main.java

Java

package com.exploit.db;
 
import com.exploit.model.C_Employee;
import com.exploit.model.Employee;
import com.exploit.model.P_Employee;
import com.exploit.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
 
public class Main {
    public static void main(String[] args)
    {
        // Get session factory using Hibernate Util class
        SessionFactory sessionFactory
            = HibernateUtil.getSessionFactory();
       
        // Get session from Session factory
        Session session = sessionFactory.openSession();
 
        // Begin transaction
        Transaction transaction
            = session.beginTransaction();
 
        // Creating Employee base class record
        Employee employee = new Employee();
        employee.setName("ChikkoRita");
        employee.setAge(19);
 
        // Creating Permanent Employee subclass record
        P_Employee permanentEmployee = new P_Employee();
        permanentEmployee.setName("Saili.H");
        permanentEmployee.setAge(18);
        permanentEmployee.setSalary(30000);
 
        // Creating Contract Employee subclass record
        C_Employee contractEmployee = new C_Employee();
        contractEmployee.setName("KirikoChan");
        contractEmployee.setAge(19);
        contractEmployee.setHourlyRate(2000);
        contractEmployee.setDuration(8.5);
 
        // persist all the employee records
        session.persist(employee);
        session.persist(permanentEmployee);
        session.persist(contractEmployee);
 
        // Commit the transaction and close the session
        transaction.commit();
        session.close();
        System.out.println(
            "Employee records successfully persisted");
    }
}

Hemos definido solo un archivo de mapeo de hibernación (hbm) Employee.hbm.xml . Las clases de modelo C_Employee y P_Employee se definen en un archivo hbm.xml . Esta es la forma habitual de mapear Table Per Subclass usando XML .

Publicación traducida automáticamente

Artículo escrito por kaalel y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *