Saltar al contenido principal

Capítulo 3: Hibernate y Estrategias DDL

Introducción​

Pregunta: ¿Cómo crea Hibernate las tablas en su base de datos?

Respuesta: Gracias a las estrategias DDL (Data Definition Language).

En este capítulo, usted comprenderá:

  • Qué es Hibernate
  • Las 5 estrategias DDL (none, validate, update, create, create-drop)
  • Cuándo usar cada estrategia
  • Cómo configurar Hibernate para PostgreSQL

¿Qué es Hibernate?​

Definición​

Hibernate es la implementación de JPA (Java Persistence API) utilizada por Spring Boot.

Analogía:

  • JPA = Interfaz (el "qué") 📄
  • Hibernate = Implementación (el "cómo") ⚙️

Ejemplo:

// JPA define la interfaz
@Entity
public class Product { ... }

// Hibernate implementa el mapeo
// Genera automáticamente el SQL

Rol de Hibernate​

Hibernate gestiona automáticamente:

  1. Mapeo Objeto-Relacional (ORM)

    • Clase Java ↔ Tabla SQL
    • Atributo Java ↔ Columna SQL
  2. Generación de SQL

    • findAll() → SELECT * FROM products
    • save() → INSERT INTO products ...
  3. Gestión del Esquema

    • Creación/modificación de tablas (estrategias DDL)

Las 5 Estrategias DDL​

Visión General​

EstrategiaComportamientoUso recomendado
noneNinguna acciónProducción (con Flyway/Liquibase)
validateValida el esquema, no modifica nadaProducción
updateActualiza el esquema (solo agrega)Desarrollo
createRecrea el esquema en cada inicioPruebas
create-dropCrea al inicio, elimina al detenerPruebas

1. ddl-auto: none​

Comportamiento: Hibernate no toca la base de datos.

Cuándo usarlo: En producción con herramientas de migración (Flyway, Liquibase).

Configuración:

spring:
jpa:
hibernate:
ddl-auto: none

Ejemplo:

Inicio de la aplicación...
→ Hibernate no crea/modifica ninguna tabla
→ Las tablas deben existir previamente

Ventajas:

  • ✅ Control total del esquema
  • ✅ Sin sorpresas en producción

Desventajas:

  • ❌ Usted debe gestionar las migraciones manualmente

2. ddl-auto: validate​

Comportamiento: Hibernate valida que el esquema corresponde a las entidades, pero no lo modifica.

Cuándo usarlo: En producción para verificar la coherencia.

Configuración:

spring:
jpa:
hibernate:
ddl-auto: validate

Ejemplo:

Inicio de la aplicación...
→ Hibernate compara las entidades con las tablas
→ Si hay diferencia → ERROR y detención

Error típico:

Schema-validation: missing column [price] in table [products]

Ventajas:

  • ✅ Detecta incoherencias
  • ✅ Asegura el inicio

Desventajas:

  • ❌ No corrige automáticamente

3. ddl-auto: update​

Comportamiento: Hibernate actualiza el esquema (agrega columnas/tablas, pero nunca elimina).

Cuándo usarlo: En desarrollo.

Configuración:

spring:
jpa:
hibernate:
ddl-auto: update

Ejemplo:

Entidad inicial:

@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
}

Base de datos:

CREATE TABLE products (
id BIGINT PRIMARY KEY,
name VARCHAR(255)
);

Modificación de la entidad:

@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
private Double price; // NUEVO
}

Inicio de la aplicación:

ALTER TABLE products ADD COLUMN price DOUBLE PRECISION;

✅ ¡Columna agregada automáticamente!


Ventajas:

  • ✅ Práctico en desarrollo
  • ✅ No necesita gestionar el esquema manualmente

Desventajas:

  • ❌ No elimina columnas obsoletas
  • ❌ Puede causar incoherencias a largo plazo
  • ❌ PELIGROSO en producción

4. ddl-auto: create​

Comportamiento: Hibernate recrea todas las tablas en cada inicio (elimina y crea de nuevo).

Cuándo usarlo: Para pruebas automatizadas.

Configuración:

spring:
jpa:
hibernate:
ddl-auto: create

Ejemplo:

Inicio de la aplicación...
→ DROP TABLE products;
→ CREATE TABLE products (...);
→ Todos los datos se PIERDEN

Ventajas:

  • ✅ Esquema siempre limpio
  • ✅ Ideal para pruebas

Desventajas:

  • ❌ PÉRDIDA TOTAL DE DATOS en cada inicio
  • ❌ NUNCA USAR EN PRODUCCIÓN

5. ddl-auto: create-drop​

Comportamiento: Como create, pero también elimina las tablas al detener la aplicación.

Cuándo usarlo: Para pruebas unitarias/integración.

Configuración:

spring:
jpa:
hibernate:
ddl-auto: create-drop

Ejemplo:

Inicio de la aplicación...
→ DROP TABLE products;
→ CREATE TABLE products (...);

... pruebas ...

Detención de la aplicación...
→ DROP TABLE products;

Ventajas:

  • ✅ Entorno de pruebas limpio
  • ✅ Sin datos residuales

Desventajas:

  • ❌ PÉRDIDA TOTAL DE DATOS
  • ❌ NUNCA USAR EN PRODUCCIÓN

Configuración Completa para PostgreSQL​

Configuración de Desarrollo​

Archivo: application-dev.yml

spring:
datasource:
url: jdbc:postgresql://localhost:5432/dev_db
username: postgres
password: ${DB_PASSWORD}
driver-class-name: org.postgresql.Driver

jpa:
hibernate:
ddl-auto: update # Práctico en desarrollo
show-sql: true # Ver las consultas
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
format_sql: true # Formatear el SQL

Configuración de Producción​

Archivo: application-prod.yml

spring:
datasource:
url: jdbc:postgresql://prod-server:5432/prod_db
username: prod_user
password: ${DB_PASSWORD}
driver-class-name: org.postgresql.Driver

jpa:
hibernate:
ddl-auto: validate # Solo validación
show-sql: false # Sin logs SQL en producción
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect

Configuración de Pruebas​

Archivo: application-test.yml

spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:

jpa:
hibernate:
ddl-auto: create-drop # Limpia después de cada prueba
show-sql: true

Dialectos de Hibernate​

¿Qué es un Dialecto?​

Un dialecto es la adaptación de Hibernate a una base de datos específica.

Analogía: Como los dialectos regionales de un idioma (español de España vs español de México).


Dialectos Comunes​

Base de DatosDialecto Hibernate
PostgreSQLorg.hibernate.dialect.PostgreSQLDialect
MySQL 8+org.hibernate.dialect.MySQL8Dialect
SQL Serverorg.hibernate.dialect.SQLServerDialect
Oracle 12c+org.hibernate.dialect.Oracle12cDialect
H2org.hibernate.dialect.H2Dialect
MariaDBorg.hibernate.dialect.MariaDBDialect

¿Por qué Especificar un Dialecto?​

Ejemplo: Generación de ID auto-incremental

PostgreSQL:

CREATE TABLE products (
id BIGSERIAL PRIMARY KEY, -- PostgreSQL
name VARCHAR(255)
);

MySQL:

CREATE TABLE products (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- MySQL
name VARCHAR(255)
);

Sin dialecto: Hibernate no sabe qué sintaxis usar.

Con dialecto: Hibernate genera el SQL correcto para su base de datos.


Logs SQL y Depuración​

Mostrar las Consultas SQL​

Configuración:

spring:
jpa:
show-sql: true # Activa los logs SQL
properties:
hibernate:
format_sql: true # Formatea el SQL para legibilidad

Consola:

Hibernate: 
insert
into
products
(name, price, id)
values
(?, ?, ?)

Mostrar los Valores de los Parámetros​

Configuración:

logging:
level:
org.hibernate.SQL: DEBUG # Logs SQL
org.hibernate.type.descriptor.sql.BasicBinder: TRACE # Valores de los parámetros

Consola:

Hibernate: 
insert
into
products
(name, price, id)
values
(?, ?, ?)

binding parameter [1] as [VARCHAR] - [Laptop]
binding parameter [2] as [DOUBLE] - [999.99]
binding parameter [3] as [BIGINT] - [1]

Estrategias Recomendadas​

Resumen Visual​

Desarrollo
↓
ddl-auto: update
show-sql: true
↓
Cambios rápidos
Tablas creadas automáticamente

---

Pruebas
↓
ddl-auto: create-drop
show-sql: true
↓
Entorno limpio
Datos eliminados después de pruebas

---

Producción
↓
ddl-auto: validate (o none)
show-sql: false
↓
Ninguna modificación automática
Migraciones gestionadas por Flyway/Liquibase

Errores Comunes​

Error 1: Table Doesn't Exist​

Error:

Table "products" doesn't exist

Causa: ddl-auto: none o validate, pero las tablas no existen.

Solución: Use ddl-auto: update o cree las tablas manualmente.


Error 2: Schema Mismatch​

Error:

Schema-validation: missing column [price] in table [products]

Causa: ddl-auto: validate, pero la entidad y la tabla difieren.

Solución:

  • Cambie a update temporalmente
  • O modifique la tabla manualmente

Error 3: Data Lost After Restart​

Error: ¡Todos mis datos desaparecen al reiniciar!

Causa: ddl-auto: create o create-drop.

Solución: Cambie a update o validate.


Resumen​

Puntos Clave​

✅ Hibernate = Implementación de JPA
✅ 5 estrategias DDL: none, validate, update, create, create-drop
✅ Desarrollo: update
✅ Producción: validate o none + Flyway
✅ Pruebas: create-drop
✅ Dialecto: Adapta Hibernate a su base de datos


Checklist Estrategias DDL​

EntornoEstrategiashow-sql
Desarrolloupdatetrue
Pruebascreate-droptrue
Producciónvalidate o nonefalse

Próximo Paso​

Ahora que domina Hibernate, pasemos al Capítulo 4 para descubrir Lombok y reducir el código boilerplate.

➡️ Capítulo 4: Lombok

⬅️ Capítulo anterior: Jakarta vs Javax

⬅️ Volver al Módulo 4