Download - Hibernate - JPA @luce 3
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