Hibernate - JPA @luce 2

Preview:

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