Este documento discute conceptos clave de Hibernate/JPA como recuperar, guardar, actualizar y eliminar entidades, y también explica diferentes tipos de relaciones como ManyToOne y OneToMany. Cubre temas como cascadas, estrategias de fetching como lazy vs eager, y cómo evitar el problema N+1 queries. El autor también menciona probar estas funcionalidades en el código de ejemplo en GitHub y discutir más temas avanzados como relaciones bidireccionales.
2. ¿Qué deberíamos saber?
•
¿Qué es Hibernate/JPA? Diferencias principales...
•
Cómo recuperar un elemento con un Id
•
Guardar/Actualizar/Eliminar
•
Una relación simple ManyToOne
3. ¿Qué vamos a ver?
•
Dudas?
•
El código está en github.
4. ¿Qué vamos a ver?
•
Cascadas
•
Más relaciones, bidirección...
6. Cascade
•
Similar a las cascades de base de datos:
o Cuando inserte este objeto, insértame también éste otro.
o Cuando elimine este objeto, eliminame éste otro.
o ...
7. Cascade
•
•
Cascade de JPA: propiedad de @ManyToOne...
o PERSIST
o MERGE*
o REMOVE
o REFRESH*
o DELETE
o ALL
Cascades de Hibernate: anotación @org.hibernate.Cascade (SAVE_UPDATE,
REPLICATE, DELETE_ORPHAN, LOCK, EVICT)
10. @OneToMany y Fetch
•
•
•
Hagamos un OneToMany a una entidad nueva, un usuario tiene varias
solicitudes.
o nueva clase Java, solicitud, hacerla entidad...
o en usuario añadir un: Set<Solicitud> solicitudes = new
HashSet<Solicitud>(); con @OneToMany
Os recomiendo crear varias solicitudes y asociarlas al mismo usuario y
trabajar siempre con éste.
Recomendación: inicializad las colecciones por defecto
11. @OneToMany y Fetch
•
•
Hibernate guarda las relaciones si las entidades asociadas no están en la base
de datos.
Si hay cascade guarda todo lo que esté marcado con cascade persist/ALL...
13. @OneToMany y Fetch *
•
•
Estrategias de Fetching -> recuperación de relaciones, directamente con un
join en el mismo momento (EAGER) o más tarde (LAZY)...
o FetchType.LAZY / EAGER
Valores por defecto:
o *ToOne: EAGER
o *ToMany: LAZY
14. @OneToMany y Fetch
•
Prueba el mapeo de solicitudes con una estrategia de fetching EAGER:
o Es un atributo de la anotación @OneToMany(_____)
15. @OneToMany y Fetch
•
Cuidado con EAGER.
o Sobre todo con entidades 'complejas'
o Hay casos en los que incluso interesa poner a LAZY un cruce *ToOne
o Se personaliza como atributo de la anotación (en el @ManyToOne(...))
o Valor personalizable en tiempo de ejecución!
o Hay una propiedad de configuración para evitar fetches excesivos:
max_fetch_depth
16. @OneToMany y Fetch
•
•
@Fetch -> formas de hacer el fetching...
o Probad las diferentes estrategias! (SUBSELECT, SELECT, JOIN)
Podemos pre-inicializar colecciones con:
o usuario.getSolicitudes().isEmpty()
o Esto no funciona: usuario.getSolicitudes() (porque no se llama a ningún
dato de la solicitud).
o Probadlo! (dejadlo en Lazy y precargad)
17. @OneToMany y Fetch
•
Pero mejor: Hibernate.initialize(usuario.getSolicitudes());
•
Por defecto, EAGER a Join y Lazy a subselect
19. @OneToMany y Fetch
•
•
•
Problema de las N+1 solicitudes:
Situación: una persona tiene varios expedientes, mapeado a Lazy y un
paginador con N elementos por página para mostrar personas y expedientes.
o Hibernate hace 1 consulta para recuperar N personas
o Después, cuando va a pintar por pantalla los expedientes, hace una
consulta para consultar el expediente de la primera persona.
o Luego otra para la segunda persona...
o Al final hace N + 1 consultas.
Se puede evitar (Eager, subselect, batch, precarga...)
20. @OneToMany y Fetch
•
•
•
@OneToMany -> por defecto con join table...
Y si quiero sin join table?
o Hay que especificar una columna a mano con @JoinColumn, él ya
entiende que no tiene que hacer que tabla de unión...
Probadlo!