Hibernate - JPA @luce 3

Preview:

DESCRIPTION

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

Citation preview

Hibernate / JPA @luce3

¿Qué deberíamos saber?

• Relaciones simples @OneToMany y @ManyToOne

• Cascades

• Tipos de fetching

¿Qué vamos a ver?

• Dudas?

• El código está en github.

¿Qué vamos a ver?

• Propietarios de la relación

• Entender la sesión...

Propietarios de la relación

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.

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.

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.

Propietarios

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

o Bidireccional?

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;

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.

• 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

Propietarios

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

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.

• 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

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

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

Listas

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.

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

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.

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.

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.

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

}

Listas

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

names = NUEVA LISTA

Relaciones avanzadas

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.

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.

Relaciones avanzadas

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

Relaciones avanzadas

• @OneToOneo foreign key o tablao compartiendo primary key

• Mapaso @MapKey(name="number")

Relaciones avanzadas

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

Más mapeos

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!

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

Tipos

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)

FAQ

FAQ

•• ...

¿Dudas?

Hibernate / JPA