Hibernate - JPA @luce 3

40
Hibernate / JPA @luce3

description

Third day of the Hibernate course, about bags, owner in oneToMany or manyToOne relations...

Transcript of Hibernate - JPA @luce 3

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