22
Hibernate / JPA @luce2

Hibernate - JPA @luce 2

Embed Size (px)

DESCRIPTION

Second day of the Hibernate course, about @OneToMany relations, bidirectional associations...

Citation preview

Page 1: Hibernate - JPA @luce 2

Hibernate / JPA @luce2

Page 2: Hibernate - JPA @luce 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

Page 3: Hibernate - JPA @luce 2

¿Qué vamos a ver?

• Dudas?

• El código está en github.

Page 4: Hibernate - JPA @luce 2

¿Qué vamos a ver?

• Cascadas

• Más relaciones, bidirección...

Page 5: Hibernate - JPA @luce 2

Cascade

Page 6: Hibernate - JPA @luce 2

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 ...

Page 7: Hibernate - JPA @luce 2

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)

Page 8: Hibernate - JPA @luce 2

Cascade

• Prueba un cascade ALL y guarda usuario con su rol

Page 9: Hibernate - JPA @luce 2

@OneToMany y Fetch

Page 10: Hibernate - JPA @luce 2

@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

Page 11: Hibernate - JPA @luce 2

@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...

Page 12: Hibernate - JPA @luce 2

@OneToMany y Fetch

• Recuperad el usuario y ver si están las solicitudes...o ...

Page 13: Hibernate - JPA @luce 2

@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

Page 14: Hibernate - JPA @luce 2

@OneToMany y Fetch

• Prueba el mapeo de solicitudes con una estrategia de fetching EAGER:o Es un atributo de la anotación @OneToMany(_____)

Page 15: Hibernate - JPA @luce 2

@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

Page 16: Hibernate - JPA @luce 2

@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)

Page 17: Hibernate - JPA @luce 2

@OneToMany y Fetch

• Pero mejor: Hibernate.initialize(usuario.getSolicitudes());

• Por defecto, EAGER a Join y Lazy a subselect

Page 18: Hibernate - JPA @luce 2

@OneToMany y Fetch

• Problema de las N+1 solicitudes

Page 19: Hibernate - JPA @luce 2

@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...)

Page 20: Hibernate - JPA @luce 2

@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!

Page 21: Hibernate - JPA @luce 2

¿Dudas?

Page 22: Hibernate - JPA @luce 2

Hibernate / JPA