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:
-
Mapeo Objeto-Relacional (ORM)
- Clase Java ↔ Tabla SQL
- Atributo Java ↔ Columna SQL
-
Generación de SQL
findAll()→SELECT * FROM productssave()→INSERT INTO products ...
-
Gestión del Esquema
- Creación/modificación de tablas (estrategias DDL)
Las 5 Estrategias DDL
Visión General
| Estrategia | Comportamiento | Uso recomendado |
|---|---|---|
| none | Ninguna acción | Producción (con Flyway/Liquibase) |
| validate | Valida el esquema, no modifica nada | Producción |
| update | Actualiza el esquema (solo agrega) | Desarrollo |
| create | Recrea el esquema en cada inicio | Pruebas |
| create-drop | Crea al inicio, elimina al detener | Pruebas |
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 Datos | Dialecto Hibernate |
|---|---|
| PostgreSQL | org.hibernate.dialect.PostgreSQLDialect |
| MySQL 8+ | org.hibernate.dialect.MySQL8Dialect |
| SQL Server | org.hibernate.dialect.SQLServerDialect |
| Oracle 12c+ | org.hibernate.dialect.Oracle12cDialect |
| H2 | org.hibernate.dialect.H2Dialect |
| MariaDB | org.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
updatetemporalmente - 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
| Entorno | Estrategia | show-sql |
|---|---|---|
| Desarrollo | update | true |
| Pruebas | create-drop | true |
| Producción | validate o none | false |
Próximo Paso
Ahora que domina Hibernate, pasemos al Capítulo 4 para descubrir Lombok y reducir el código boilerplate.