Top Banner
Hibernate / JPA @luce3
40

Hibernate - JPA @luce 3

Jun 13, 2015

Download

Technology

Javier Gamarra

Third day of the Hibernate course, about bags, owner in oneToMany or manyToOne relations...
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Hibernate - JPA @luce 3

Hibernate / JPA @luce3

Page 2: Hibernate - JPA @luce 3

¿Qué deberíamos saber?

• Relaciones simples @OneToMany y @ManyToOne

• Cascades

• Tipos de fetching

Page 3: Hibernate - JPA @luce 3

¿Qué vamos a ver?

• Dudas?

• El código está en github.

Page 4: Hibernate - JPA @luce 3

¿Qué vamos a ver?

• Propietarios de la relación

• Entender la sesión...

Page 5: Hibernate - JPA @luce 3

Propietarios de la relación

Page 6: Hibernate - JPA @luce 3

Propietarios

• Relaciones unidireccionales:o Un usuario tiene un rol, pero no al revés.

• Relación bidireccional:o Un usuario tiene un conjunto de solicitudes y cada solicitud tiene

asociado ese mismo usuario.

Page 7: Hibernate - JPA @luce 3

Propietarios

• Propietario: es el responsable de la actualización/inserción de la relación.

o Ejemplo: una solicitud tiene asociado unos datos económicos. Cuando inserto la solicitud quiero que se inserten sus datos económicos. El responsable de la relación es la solicitud.

o Sólo puede haber un responsable de una relación.

Page 8: Hibernate - JPA @luce 3

Propietarios

• En las relaciones unidireccionales:o El responsable es el lado que tiene el mapping (mapeo).

• En las relaciones bidireccionales:o HAY que especificar el responsable de la relación.

Page 9: Hibernate - JPA @luce 3

Propietarios

• @OneToMany... hemos visto:o Unidireccionalo Unidireccional con join table

o Bidireccional?

Page 10: Hibernate - JPA @luce 3

Propietarios

• Bidireccional. Lado propietario en el @ManyToOne

o (recomendado!)

o De esta forma:

Usuario: @OneToMany (mappedBy="usuarioEJEMPLO")

Solicitud: @ManyToOne @JoinColumn("nombre de la columna") private Usuario usuarioEJEMPLO;

Page 11: Hibernate - JPA @luce 3

Propietarios

• Probadlo!

o La solicitud tiene un atributo Usuario con un @ManyToOne

o El usuario tiene una propiedad mappedBy dentro del @OneToMany que apunta al NOMBRE del atributo usuario en la solicitud.

Page 12: Hibernate - JPA @luce 3

• En el otro lado:

o Lado del One: JoinColumn con name="lo_que_sea", insertable = false, updatable = false;

o Lado del Many: JoinColumn con name="lo_que_sea".

• Probadlo!

o Usuario apuntando a una set de solicitudes con @OneToMany SIN mappedBy

o Solicitud apuntando a un Usuario con @ManyToOne y propiedades insertable=false, updatable=false (hay varios @JoinColumn pero uno no es insertable).

Propietarios

Page 13: Hibernate - JPA @luce 3

Propietarios

• ¿Qué pegas véis?o ...

Page 14: Hibernate - JPA @luce 3

Propietarios

• Ligeramente más ineficiente, ojo con Envers (auditoría)

o Insert y luego un update (por PK).

• La foreign key no puede tener NOT NULL.

Page 15: Hibernate - JPA @luce 3

• Sólo, sólo, sólo puede haber un sitio en el que se mapean físicamente las columnas para ser insertadas (sólo un @JoinColumn con insertable=true, updatable=true)

• Por favor, haced las operaciones en los dos lados.o Si añado una solicitud a un usuario, también llamo a el setUsuario de

solicitud.o Si llamo a setUsuario de solicitud también añado la solicitud a la lista de

solicitudes de usuario.

Propietarios

Page 16: Hibernate - JPA @luce 3

Propietarios

• Poner mal el propietario de la relación introduce errores sutiles...

• He creado un ejemplo para verlo con Historial, que tiene una lista de expedientes y Expediente que tiene un Historial.

• El responsable debería ser Historial, pero nos hemos colado...

Page 17: Hibernate - JPA @luce 3

Propietarios

• Regla de Oro para relaciones bidireccionales en relación padre-hijos:

o Si la entidad importante es el padre -> insertable = false, updatable = false en el HIJO

o Si la entidad importante es el hijo -> mappedBy en el PADRE

Page 18: Hibernate - JPA @luce 3

Listas

Page 19: Hibernate - JPA @luce 3

Listas

• Sets? y listas?

• Una lista tiene ORDEN, si no tiene orden es un "Bag"o Un conjunto de elementos sin orden/sin indexaro Elementos repetidos: viola el principio de unicidad de tuplas del modelo

relacionalo Cannot simultaneously fetch multiple bags -> sólo se puede recuperar a

Eager una sola bag.o Envers no lo soporta.

Page 20: Hibernate - JPA @luce 3

Listas

• S1 Euro• S1 Euro• S1 Paseo Zorrilla

S1 -> 3 direcciones (Euro, Euro, Paseo Zorrilla) 1 única bolsa

S1 1 Euro Portal 1S1 2 Euro Portal 2S1 P Zorrilla Portal 3

Page 21: Hibernate - JPA @luce 3

Listas

• Y funciona? Poner un List?o Sí. Pero no lo hagáis si podéis evitarlo.

• Si tenemos orden, lo mapeamos con @OrderColumn (hibernate no te crea la columna automáticamente)

• Si no tenemos orden, mapeamos un Set. o Si necesitamos una lista, creamos un método que devuelva una lista a

partir del Set.o Las operaciones de persistencia las hacemos sobre el Set.

Page 22: Hibernate - JPA @luce 3

Listas

• Caso de prueba:o Mapead una relación bidireccional entre solicitud y datos bancarios

(pueden ser varios para una solicitud) (me da igual que propietario mientras lo entendais).

o Guardad varios datos bancarios.

Page 23: Hibernate - JPA @luce 3

Listas

• Hibernate comprueba si las colecciones han cambiado, por identidad de Java (el resto de cosas por valor).

• Le obliga a guardar toda la colección, no sabe que no han cambiado los componentes.

• Llamad a add(), addAll() y remove() cuando queráis interaccionar con elementos de una lista.

Page 24: Hibernate - JPA @luce 3

Listas

• No hagáis estas cosas (con names anotado):

public void setNames(List namesList) {

names = (String[]) namesList.toArray();

}

public List getNames() {

return Arrays.asList(names);

}

Page 25: Hibernate - JPA @luce 3

Listas

• O no hagáis esto para incluir nuevos elementos o borrar:

names = NUEVA LISTA

Page 26: Hibernate - JPA @luce 3

Relaciones avanzadas

Page 27: Hibernate - JPA @luce 3

Relaciones avanzadas

• ManyToManyo Unidireccionalo Bidireccional: mappedBy

• Excesivamente compleja, mejor evitarla o mapearla como dos relaciones (@OneToMany y @ManyToOne).

• Si no existen las tablas, mejor, porque genera el esquema correcto.

Page 28: Hibernate - JPA @luce 3

Relaciones avanzadas

• La relación consiste en un nombre específico para la tabla de unión:o joinTable (name)

• y los nombres de las columnas de unión: o joinColumns e inverseJoinColumns.

Page 29: Hibernate - JPA @luce 3

Relaciones avanzadas

• @CollectionOfElements, una lista de valores simpreso @ElementCollectiono @CollectionTable(name="___", joinColumns=@JoinColumn(name="__"))

Page 30: Hibernate - JPA @luce 3

Relaciones avanzadas

• @OneToOneo foreign key o tablao compartiendo primary key

• Mapaso @MapKey(name="number")

Page 31: Hibernate - JPA @luce 3

Relaciones avanzadas

• Las relaciones es la parte más complicada (IMHO) de Hibernate:o Tirar de referencia

Page 32: Hibernate - JPA @luce 3

Más mapeos

Page 33: Hibernate - JPA @luce 3

Más mapeos de columnas

• @Formulao Para incluir SQL directamente en un mapeo.o También subselectso Pruebalo!

• @Temporal(...)o Para mapear el caos de tipos de fechas diferentes dependiendo de la BD.o Pruebalo!

Page 34: Hibernate - JPA @luce 3

Más mapeos de columnas

• @Enumeratedo Para mapear una enumeración

• @Sort/@Whereo Ordenación y restricciones por defecto!

• @Lobo Para mapear un lob/clob...

Page 35: Hibernate - JPA @luce 3

Tipos

Page 36: Hibernate - JPA @luce 3

Tipos

• Detrás de los mapeos hay tipos de Hibernate:o Valores (org.hibernate.type.StringType)o Compuestos (les veremos mañana...)o Coleccioneso Custom (los que yo defina)

Page 37: Hibernate - JPA @luce 3

FAQ

Page 38: Hibernate - JPA @luce 3

FAQ

•• ...

Page 39: Hibernate - JPA @luce 3

¿Dudas?

Page 40: Hibernate - JPA @luce 3

Hibernate / JPA