Upload
javier-gamarra
View
415
Download
2
Embed Size (px)
DESCRIPTION
Second day of the Hibernate course, about @OneToMany relations, bidirectional associations...
Citation preview
Hibernate / JPA @luce2
¿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
¿Qué vamos a ver?
• Dudas?
• El código está en github.
¿Qué vamos a ver?
• Cascadas
• Más relaciones, bidirección...
Cascade
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 ...
Cascade
• Cascade de JPA: propiedad de @ManyToOne...o PERSISTo MERGE*o REMOVEo REFRESH*o DELETEo ALL
• Cascades de Hibernate: anotación @org.hibernate.Cascade (SAVE_UPDATE, REPLICATE, DELETE_ORPHAN, LOCK, EVICT)
Cascade
• Prueba un cascade ALL y guarda usuario con su rol
@OneToMany y Fetch
@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
@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...
@OneToMany y Fetch
• Recuperad el usuario y ver si están las solicitudes...o ...
@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: EAGERo *ToMany: LAZY
@OneToMany y Fetch
• Prueba el mapeo de solicitudes con una estrategia de fetching EAGER:o Es un atributo de la anotación @OneToMany(_____)
@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 *ToOneo 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
@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)
@OneToMany y Fetch
• Pero mejor: Hibernate.initialize(usuario.getSolicitudes());
• Por defecto, EAGER a Join y Lazy a subselect
@OneToMany y Fetch
• Problema de las N+1 solicitudes
@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 personaso 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...)
@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!
¿Dudas?
Hibernate / JPA