Saltar navegación

20260129 JPA_11 - Contenido educativo

Ajuste de pantalla

El ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:

Subido el 1 de febrero de 2026 por Raquel G.

5 visualizaciones

Descargar la transcripción

Vale, entonces esto en resumen, las entidades JPA ya en mi modelo Java están relacionadas entre sí porque las entidades tienen objetos de las otras entidades. Esa es la forma en la que se expresa que están relacionadas. 00:00:01
Entonces, cuando ya se cargue el contexto de persistencia 00:00:19
El entity manager que es aquí 00:00:23
Y ya aparezcan nuestros objetos persistentes 00:00:24
Bien, porque los hemos recuperado de la base de datos con un find 00:00:27
O bien, porque los hemos creado nuevos en la aplicación 00:00:31
Como transitorios y hemos hecho el persist 00:00:35
Para que se conecten 00:00:37
Son las dos maneras de tener objetos persistentes 00:00:38
Ya tenemos nuestros objetos persistentes 00:00:40
Ya sabemos que la dinámica en JPA es 00:00:43
Yo ya modifico las propiedades de los objetos 00:00:46
Y con los commits 00:00:48
Esas modificaciones 00:00:51
Se trasladarán a la actualización 00:00:52
De los campos correspondientes 00:00:55
¿Vale? 00:00:56
Se trasladarán 00:00:58
Aquí en jugador 00:00:59
Si yo cambio el objeto equipo 00:01:00
Si lo cambio 00:01:03
Hago un equipo nuevo 00:01:05
Al jugador le hago set equipo 00:01:08
Ese equipo 00:01:10
Trabajo con los objetos de la base de datos 00:01:11
Ni la miro, me olvido de ella 00:01:13
Pues cuando llegue el commit 00:01:14
automáticamente 00:01:16
ya JPA 00:01:19
se encargará de meter en esta 00:01:21
en este campo 00:01:24
de la tabla jugador 00:01:25
el ID correspondiente al equipo 00:01:28
que tú has puesto como objeto aquí y ya se encarga 00:01:30
de todo eso, ¿verdad? 00:01:32
Esa es la clave de JPA 00:01:33
el truco de JPA, yo tengo objetos persistentes 00:01:35
los toco en Java 00:01:38
los toco cambiando propiedades 00:01:40
moviendo, agregando, quitando 00:01:41
y eso, mágicamente 00:01:43
entre comillas, se va correspondiendo 00:01:46
a la actualización de los campos 00:01:48
de la base de datos, esa es la idea, por eso hacemos esto 00:01:50
y así no tenemos que hacer ni SQL 00:01:52
ni nada de eso 00:01:54
a ver, cuando tú seteas un equipo 00:01:54
ese equipo tendrá un objeto 00:02:02
que tendrá un ID 00:02:04
y ese ID 00:02:05
la primera vez que lo creas 00:02:06
entonces aparecerá el ID 00:02:14
solo cuando se haga persistente 00:02:16
¿vale? entonces para hacerse 00:02:18
persistente este equipo lo tendrías que hacer tú antes 00:02:20
con un persist y luego hacerle el set 00:02:22
equipo, pero después de haber hecho tú 00:02:24
el, creas el equipo persist 00:02:26
a ese equipo ya le aparece 00:02:28
su ID ¿vale? 00:02:30
entonces 00:02:32
cuando luego tú hagas jugador 00:02:33
set equipo ese equipo pues ya automáticamente 00:02:36
JPA 00:02:38
en el campo ID equipo ID 00:02:39
de esa tabla lo pondrá etc 00:02:41
¿vale? entonces 00:02:43
para ti es transparente ese ID 00:02:45
o también puedes haber cogido el equipo 00:02:47
de la base de datos porque cambias al jugador 00:02:54
de equipo, entonces haces un find, luego lo haces 00:02:55
el set, bueno pues entonces 00:02:57
lo que estaba 00:02:59
diciendo, que en las relaciones 00:03:01
sean de uno a uno 00:03:03
de uno a muchos o de muchos a muchos 00:03:06
para JPA hay uno 00:03:08
que es el que manda, el propietario 00:03:10
y otro 00:03:12
que no es el que manda 00:03:14
entonces el que manda es siempre 00:03:15
el que tiene 00:03:17
el extremo many 00:03:20
¿vale? el extremo many 00:03:21
el que tiene el extremo many 00:03:23
es el que tiene en la tabla 00:03:25
el campo 00:03:27
jugador es el que tiene en su 00:03:28
tabla el campo, es el que lo tiene 00:03:31
equipo no tiene jugador id 00:03:33
no lo necesita, ese es el que manda 00:03:35
entonces el que manda significa 00:03:37
que tú puedes actualizar 00:03:39
a través de jugador el equipo 00:03:41
y si tú tienes un jugador 00:03:43
con un equipo y haces jugador 00:03:46
get equipo y cambias del equipo 00:03:48
el nombre, pues a través del jugador 00:03:50
puedes tocar el equipo, porque el jugador 00:03:52
manda, pero al revés no 00:03:54
aquí en 00:03:56
pero estas cosas 00:03:57
son pequeños comportamientos 00:03:59
matices, cosas que cuando uno trabaja con esto 00:04:01
pues te vas encontrando y ya está 00:04:04
y tampoco tiene mayor 00:04:05
pruebas y de uy, ¿por qué no lo actualizáis? 00:04:07
aquí por ejemplo en equipo 00:04:10
Tienes 00:04:12
Una lista de jugadores 00:04:13
Entonces tú podrías pensar 00:04:15
Yo voy a 00:04:17
Añadirle 00:04:19
Voy a cambiar el equipo de un jugador 00:04:21
Entonces tú podrías plantearte 00:04:23
Intentar hacerlo desde este extremo 00:04:25
Que es, cojo ese jugador 00:04:27
Con el find 00:04:29
Lo meto en la lista 00:04:30
Pues ya está, si lo he metido en la lista 00:04:32
Cuando yo haga el commit 00:04:35
Ya JPA será capaz de decir 00:04:37
Oye, en esta lista está este jugador 00:04:39
pues voy a cambiar el jugador y de 00:04:41
no, no lo va a hacer porque esta no es 00:04:43
la que manda en la relación 00:04:45
entonces de la que se genera el SQL es de la 00:04:47
propietaria, de la otra 00:04:49
bueno, entonces eso pues que 00:04:50
os suene, aunque no haya necesidad 00:04:53
de conocer todos los detalles 00:04:56
ahora mismo, porque es un problema 00:04:57
típico que tú crees que, pero ¿por qué no se actualiza? 00:04:59
¿por qué no se actualiza? Estás partiendo del extremo 00:05:02
que no es correcto, bueno, de hecho ahora lo vamos a 00:05:03
a ver en un ejemplo 00:05:05
bueno, pues entonces 00:05:08
Estas son las entidades que estamos mapeando 00:05:09
Jugador tiene su equipo 00:05:12
Jugador tiene 00:05:14
Puede tener un perfil 00:05:16
Gamer 00:05:19
Que es aquí 00:05:21
Aquí por eso hay una 00:05:22
O puede no tenerlo 00:05:24
Por eso aquí hay un 00:05:26
Las anotaciones 00:05:27
Pueden tener un montón de atributos 00:05:29
Que las caracterizan 00:05:32
Uno de ellos es el nulable 00:05:33
Entonces aquí el nulable 00:05:35
Por defecto creo que suele ser true 00:05:37
Que es el que nos interesa 00:05:41
O sea, el jugador no tiene por qué tener obligatorio 00:05:42
Un perfil gamer 00:05:44
¿Vale? No tiene por qué 00:05:45
Si quisiéramos que tuviera obligatoriamente uno 00:05:47
Pues habría que poner un nulable igual false 00:05:50
Propiedades 00:05:52
Esta otra propiedad 00:05:53
Recordad que significaba 00:05:55
Que a través de jugador 00:05:57
Se traslada la persistencia 00:05:58
A su 00:06:01
A su relacionado perfil gamer 00:06:02
¿Vale? 00:06:06
Si yo hago un jugador, le meto un perfil, todo esto en objeto transitorio los dos, jugador y perfil, y hago un persist de jugador, pues el persist viaja en cascada hasta este y también se hará el persist del perfil gamer de este objeto, ¿vale? 00:06:06
Sin embargo, si yo no pongo este atributo, por defecto no se hace ninguna cascada, ni en Persis, ni en Remus, ni en nada. 00:06:23
Bueno, aquí tenemos el otro extremo de la relación y ahora esta ya sí era la relación de muchos a muchos entre jugador y videojuego, que la hacíamos a través de esta tabla, ¿vale? 00:06:33
Entonces esta tabla es la que se supone 00:06:49
Que mapea, perdón 00:06:52
Esta entidad es la que mapea 00:06:54
Esta tabla, esa entidad 00:06:56
Es la que la mapea 00:06:58
Y esta entidad tiene entonces 00:06:59
Un jugador y un videojuego 00:07:02
Que son los otros extremos 00:07:04
Los many to one 00:07:06
De aquí 00:07:07
De este 00:07:09
Y en videojuego igual 00:07:11
Videojuego 00:07:14
Tiene esta de aquí 00:07:17
Que es el otro extremo 00:07:18
De esta de aquí 00:07:21
Y luego además tiene 00:07:23
Estos dos propiedades 00:07:26
¿Vale? 00:07:29
Pues cuando no haya estado 00:07:36
Ahora vamos a quitar el estado 00:07:37
Vamos a hacer una versión 00:07:39
De por ejemplo 00:07:40
De que esta aplicación 00:07:43
La jugador videojuego 00:07:44
No interesa ni la posición en la que juegas 00:07:46
En ese videojuego ni el nivel en el que estás 00:07:48
entonces si no hace falta 00:07:50
esta entidad desaparece 00:07:51
entonces tienes que poner many to many en las otras 00:07:54
vale, pues entonces 00:07:56
aquí, ¿qué ocurre con esta tabla? 00:07:58
bueno, videojuego no hay mucho que mirar porque ya tenía 00:08:00
nada, este otro extremo y ya está 00:08:02
y luego el perfil gamer 00:08:04
que tampoco tiene mucho que mirar 00:08:06
tiene su clave primaria y sus propiedades 00:08:07
y la anotación 00:08:10
one to one que lleva aquí 00:08:12
one to one 00:08:14
entonces, en perfil gamer 00:08:16
Aquí marcamos la columna dentro de la tabla 00:08:18
Perfil gamer que te lleva al jugador 00:08:21
Y estas no tienen nada más 00:08:23
Entonces aquí, esta 00:08:25
Clave primaria 00:08:26
Todas las entidades tienen que tener una clave 00:08:28
Es evidente, porque JPA 00:08:30
Trabaja con sus claves 00:08:32
Clave primaria 00:08:34
Las dos 00:08:36
Pues entonces nosotros podemos 00:08:37
Tranquilamente poner aquí esto y esto 00:08:40
Y ya está 00:08:42
Y quedarnos tan tranquilos 00:08:44
y quedarnos tan tranquilos 00:08:45
y esto pues 00:08:48
funciona, entonces vamos a hacer 00:08:49
ahora alguno, os puse una lista de servicios 00:08:52
igual habéis hecho algunos 00:08:54
a lo mejor habéis 00:08:56
metido 00:08:58
que sería lo ideal, claro, un patrón DAO 00:08:59
para cada entidad, un DAO 00:09:02
para cada entidad y luego esos servicios 00:09:04
que utilicen el DAO que sea 00:09:06
vale, entonces el DAO 00:09:07
como es la clase estándar, sota, caballo y rey 00:09:09
pues crear, recuperar 00:09:12
delete, no sé qué 00:09:14
pues como ahora lo que nos interesa 00:09:15
es la parte de JPA 00:09:18
me voy a saltar el dado 00:09:19
vamos a hacer unos servicios 00:09:22
que directamente puentean el dado 00:09:23
llaman ya al persist, al find, a lo que sea 00:09:25
para ir rápidos 00:09:27
pero bueno 00:09:30
entonces vamos a hacer algún servicio 00:09:31
de esos y alguno en particular 00:09:34
para que nos va a llevar 00:09:36
a ver cómo es 00:09:38
mapear las claves de la 00:09:39
tabla conjunta 00:09:42
sí puede ser un poco farragoso 00:09:44
y en ciertas condiciones incluso 00:09:46
podría inducir terror 00:09:48
vale, entonces, ¿qué servicio tenía yo pensado para 00:09:49
ver esto? se me había olvidado, aparte podemos 00:09:52
hacer cualquiera de los servicios que 00:09:54
hayáis hecho vosotros en casa o algún otro que 00:09:55
queráis que hagamos 00:09:58
entonces, vamos a ver 00:09:59
bueno, pues yo aquí tenía 00:10:01
mi clase de servicios 00:10:05
directamente, esta 00:10:09
que puentea al DAO tal cual 00:10:10
¿vale? 00:10:13
vale, pues entonces 00:10:15
este es el servicio que yo quería 00:10:16
que viéramos 00:10:18
porque no se me ha comentado 00:10:23
porque ya está comentado ahí 00:10:27
ah, pues no le debió dar 00:10:29
con suficiente fuerza 00:10:34
vale 00:10:35
este de aquí es una toma 00:10:37
vale, pues ya está 00:10:39
vale, pues vamos a hacer un 00:10:40
servicio que implique 00:10:43
tocar esa tabla 00:10:45
Que implique tocar esa tabla 00:10:47
Eliminar de un videojuego 00:10:48
Vamos a eliminar un jugador 00:10:51
No sé si ese lo habéis hecho 00:10:52
Es uno de los que a lo mejor hayáis hecho 00:10:54
Vale, pues lo que sí que vamos a respetar 00:10:55
Es que el servicio 00:11:07
Maneje la transacción 00:11:08
El servicio 00:11:11
Se corresponde con una transacción 00:11:13
Eso sí que es lo habitual 00:11:16
¿Vale? 00:11:17
Y los dados no 00:11:19
Entonces 00:11:20
Dime 00:11:22
La clase de servicios 00:11:26
¿Cuándo la creaste? 00:11:28
La, no la creé 00:11:30
Pero a ver, la puedes crear tú ahora 00:11:32
Es solo hacer una clase de servicios y ya está 00:11:33
Una clase de servicios, ya está 00:11:35
¿Vale? 00:11:38
00:11:40
¿Qué viejo estás? 00:11:40
¿Por qué? 00:11:51
Porque va así 00:11:52
Vale 00:11:53
es una clase servicios 00:11:56
en la que he dicho 00:11:58
que voy a poner 00:11:59
algunos servicios 00:12:00
para ejemplificar cosas 00:12:01
puenteando el DAO 00:12:02
porque si nos ponemos 00:12:03
a hacer ahora un DAO 00:12:04
con todas las entidades 00:12:05
que hay 00:12:06
todos nos estamos 00:12:06
mil horas 00:12:06
pero no pasa nada 00:12:07
le podéis 00:12:08
le podéis decir a HGPT 00:12:09
dame unos DAOs 00:12:10
y nos hablamos de tiempo 00:12:11
pero ni eso 00:12:12
vamos a puentear el DAO 00:12:14
porque hacer el DAO 00:12:15
es que ya sabemos 00:12:16
lo que es 00:12:16
el create 00:12:17
pues persist 00:12:17
el get 00:12:18
pues fine 00:12:19
ya está 00:12:20
otra cosa es que 00:12:21
luego la arquitectura 00:12:23
de clases que hagamos 00:12:24
que lo hagamos 00:12:25
como uno genérico 00:12:26
y ya está, y luego la implementación 00:12:27
pues se haga para equipo 00:12:30
class, jugador class, o que hagamos 00:12:32
uno para cada uno, eso ya son detalles de 00:12:34
diseño, ¿vale? pero lo que 00:12:36
al fin y al cabo hace el DAO es eso 00:12:38
el persist, el find 00:12:40
pues en lugar de llamar al DAO para hacer el persist 00:12:42
y el find, vamos a hacerlo desde el servicio directamente 00:12:44
y ya está, para no estar aquí escribiendo mil clases 00:12:46
¿vale? entonces 00:12:48
esta es mi clase servicios con algunas 00:12:50
cosas por aquí que no hicimos 00:12:52
el otro día, porque 00:12:54
hice yo en casa y que están ahí abandonadas 00:12:56
y este método 00:12:58
que si era el que quería que viéramos, pues por ejemplo 00:12:59
vamos a eliminar un jugador de un videojuego que es así 00:13:02
que va a tocar la tabla de muchos 00:13:04
a muchos 00:13:06
vale, tenemos que pasarle el 00:13:06
contexto de persistencia 00:13:10
vale, o podría 00:13:12
trabajar 00:13:15
con un contexto de persistencia 00:13:17
como propiedad 00:13:19
aquí que se le inyectará por constructor 00:13:20
lo que pasa es que entonces 00:13:23
no podemos cerrarlo en cada servicio 00:13:28
el contexto de persistencia 00:13:30
va a estar vivo 00:13:32
todo el tiempo de la aplicación 00:13:34
eso bueno, puede ser un poco 00:13:36
peligroso en cuanto a cachés de objetos 00:13:38
a la hora de hacer el hibernate 00:13:40
la sincronización 00:13:42
normalmente es más habitual 00:13:43
que el contexto de persistencia se abra y se cierre aquí 00:13:46
para lo cual hay que inyectárselo 00:13:48
al método 00:13:50
en estas últimas frases mías 00:13:51
ya se empieza a ver 00:13:53
que es un poco aburrido 00:13:56
en JPA 00:13:57
gestionar objetos que es que van a estar 00:14:00
sí o sí, como el contexto de 00:14:02
persistencia, las transacciones, todo eso 00:14:04
pues entonces 00:14:06
por eso es por lo que Spring dice 00:14:08
Spring JPA dice 00:14:10
que rápido 00:14:11
por eso es por lo que 00:14:15
Spring Data JPA 00:14:19
con lo que todavía no nos hemos metido 00:14:20
dice no, no, no, no, no 00:14:22
tú olvídate, tu programa 00:14:24
Olvídate de Entity Manager 00:14:26
Olvídate de Transacciones, Commit 00:14:28
Olvídate de todo eso 00:14:31
Yo ya lo crearé cuando haga falta 00:14:32
Lo meteré cuando haga falta 00:14:35
Pues sí 00:14:36
Spring, no JPEG 00:14:37
Entonces, pues sí, qué cómodo 00:14:41
Pero, ostras, cuando salen errores 00:14:42
Antes de echar GPT 00:14:46
Te estabas 17 horas 00:14:50
Después de echar GPT te estás una 00:14:52
Pero te estás una 00:14:53
Entonces sigues en un rollo 00:14:55
Bueno, a ver, entonces 00:14:57
Eliminar jugador de videojuego 00:14:59
¿Qué le vamos a pasar? Pues las claves de los jugadores 00:15:00
A este jugador 00:15:03
¿Vale? 00:15:08
Le vamos a eliminar 00:15:10
De este videojuego 00:15:13
Este sería nuestro método de servicio 00:15:15
Ya está 00:15:20
Vale, como vamos a actualizar la base de datos 00:15:23
¿Eh? 00:15:27
Que me sobra una llave por ahí 00:15:28
Sí está 00:15:29
Como vamos a actualizar la base de datos 00:15:31
Estas cosas sí que pueden ser 00:15:33
Típicas pues de examen 00:15:35
Que yo 00:15:38
Lo que tendréis que hacer en el examen son servicios 00:15:39
Servicios de costos 00:15:41
Pues 00:15:43
No hay problema 00:15:44
Vamos sobraos 00:15:47
Y que no de errores, claro 00:15:48
Y que haga lo que tenga que hacer 00:15:51
Entonces 00:15:53
Vamos a actualizar la base de datos 00:15:54
Aquí habrá que hacer una transacción 00:15:56
sí o sí 00:15:59
entonces de nuevo 00:16:02
qué rollo tener la que gestionar a mano 00:16:07
si esprime la gestionara 00:16:09
qué bien, ya, pero la gestiono 00:16:12
y yo, hombre, yo decido dónde está 00:16:14
han decidido qué transacciones 00:16:15
quiero, cuáles no, pues hombre 00:16:17
decido, no me anulan como ser humano 00:16:19
pues entonces 00:16:21
uno podría decir, vale, pues vamos a coger 00:16:23
primero el jugador y el videojuego 00:16:26
vale 00:16:27
entonces 00:16:29
Cogemos 00:16:30
Jugador 00:16:33
J igual a new 00:16:34
Jugador 00:16:37
No, ¿por qué digo yo new? 00:16:40
End.find 00:16:42
Jugador 00:16:43
Punto 00:16:47
Class y aquí la clave 00:16:49
Id de jugador 00:16:51
Videojuego 00:16:52
V igual a 00:17:03
End.find 00:17:05
videojuego.class 00:17:10
videojuego 00:17:18
entonces ya tenemos estas entidades 00:17:20
que tenemos que 00:17:26
desasociar 00:17:27
entonces aquí 00:17:29
tal y como 00:17:32
lo tenemos planteado 00:17:34
pues 00:17:35
hay varios caminos por los que podemos atacar 00:17:36
pero son todos un poco liosos 00:17:40
me puedo sacar el videojuego 00:17:42
y decir vale voy a quitar 00:17:44
del videojuego 00:17:46
la asociación que tiene con el jugador 00:17:47
¿vale? que es lo que 00:17:51
aquí, a ver 00:17:52
jugador 00:17:58
punto get 00:18:02
jugador videojuegos 00:18:03
y entonces 00:18:05
si jpafuera tan potente y tan 00:18:07
pues tendríamos que hacer aquí 00:18:09
vale, de jugador videojuegos que es la lista 00:18:12
voy a borrar 00:18:14
voy a borrar 00:18:16
el que voy a borrar 00:18:18
un juego, perdón 00:18:19
Un jugador videojuego 00:18:21
Que sea igual al que tiene esto de aquí 00:18:23
¿Vale? Entonces esto tendría sentido 00:18:25
Hacerlo, en Java esto tiene sentido 00:18:27
New 00:18:29
Jugador 00:18:30
Videojuegos 00:18:34
Y ahora 00:18:36
Tengo un constructor en jugador videojuego 00:18:41
Bueno, vamos a hacerlo 00:18:45
Para que no quede la línea 00:18:47
Tan grande, tan larga 00:18:49
Lo voy a hacer aparte 00:18:50
Jugador videojuego 00:18:51
no, los dos lo tengo que pasar, jugador videojuegos se caracteriza por los dos, jugador videojuegos jv igual a new, jugador videojuegos, vale, y ahora, jugador videojuego, perdón, jugador videojuego, 00:18:54
Y ahora a jugador videojuego 00:19:15
Set jugador el J 00:19:21
Y jugador videojuego 00:19:23
Set 00:19:27
Videojuego el V 00:19:28
¿Vale? 00:19:31
Entonces 00:19:41
Este remove 00:19:42
Ya sabemos 00:19:44
Jugador videojuegos 00:19:46
Ya sabemos que funciona 00:19:47
Si hay un equals 00:19:51
Lógicamente 00:19:53
¿Vale? Entonces yo aquí 00:19:54
Haría mi 00:19:56
Transaction.commit 00:19:58
Y en .close 00:20:04
¿Vale? 00:20:07
Entonces 00:20:10
Esto 00:20:10
En principio tiene sentido 00:20:12
¿Vale? 00:20:14
Pero primera cosa que aquí habría que retocar 00:20:15
Esto solo funciona, lógicamente 00:20:18
Si hay un equals 00:20:20
Si hay un equals en jugador videojuego 00:20:22
por jugador 00:20:24
y por videojuego, lógicamente 00:20:27
porque el remove te borra 00:20:29
un objeto igual a este 00:20:31
dentro de la colección, igual a este 00:20:33
luego tiene que haber un equals basado en jugador y videojuego 00:20:35
y es que ese equals 00:20:37
tiene sentido 00:20:39
entonces, jugador videojuego 00:20:40
pues no pasa nada, le hacemos 00:20:42
le hacemos a jugador y videojuego 00:20:44
un hashcode e equals 00:20:48
nada, se lo hace 00:20:49
y generar hashcode e equals 00:20:51
Por jugador y por videojuego 00:20:53
Pero cuidadín, no perdáis la línea 00:20:56
El equals por jugador y videojuego 00:21:08
También va a implicar 00:21:12
Que esté el equals dentro de jugador 00:21:14
Y el equals dentro de videojuego 00:21:16
Lógicamente 00:21:18
Porque el equals de jugador y videojuego 00:21:19
Mira a ver si jugador es igual a jugador 00:21:22
Y videojuego es igual a videojuego 00:21:24
Con lo cual jugador y videojuego 00:21:26
Tienen que tener su propio equals 00:21:28
Pero ese equals estará basado en id 00:21:30
Pues nada, le hacéis a jugador 00:21:33
Un equals basado en el id 00:21:35
Que os quedará como este 00:21:38
Y a videojuego 00:21:43
Otro equals basado en su id 00:21:45
Que os quedará como este 00:21:47
Porque da lo mismo 00:21:51
O sea, da igual, por cualquiera de los dos 00:22:05
Llegas a la misma, en JPA está todo duplicado 00:22:08
¿Vale? 00:22:10
Claro, que puedes hacer 00:22:13
V.g 00:22:14
Vale, entonces 00:22:15
Y ahora me quedo aquí con mi servicio 00:22:18
Que está aquí 00:22:24
Vale 00:22:26
Entonces este es un ejemplo de muchas cosas 00:22:27
Que vamos a probarlo 00:22:30
Entonces 00:22:33
Yo en mi tabla 00:22:35
No sé vosotros en la vuestra 00:22:36
Pero yo en la mía tengo 00:22:38
Al jugador 3 00:22:41
En el videojuego 2 00:22:42
Voy a intentar quitarlo 00:22:44
Al jugador 3, videojuego 2 00:22:47
Primero le estoy dando 00:22:48
el jugador y luego el videojuego, vale, entonces haceos un main 00:22:52
un main normal y corriente, haceos un main 00:22:56
para probar los servicios, vale 00:23:00
este es mi main, donde me instancio servicios para probarlo 00:23:06
esto todo lo voy a dejar comentado porque son mis 00:23:09
pruebas, esta es la que me interesa 00:23:14
haceos un main 00:23:22
que instancia esta clase 00:23:25
y vamos a eliminar jugador 00:23:26
videojuego, en mi caso 00:23:32
voy a eliminar el jugador 3 00:23:34
videojuego 2 00:23:36
recordad que aquí hay que pasarle 00:23:37
el contexto de persistencia, el entity manager 00:23:47
yo por eso me he copiado 00:23:49
la clase jpa útil del otro proyecto 00:23:51
y ya está, por eso os copiáis la clase 00:23:54
si es que no la tenéis copiada 00:23:56
el paquete entero 00:23:57
os copiáis el paquete entero del otro proyecto y se acabó 00:23:58
¿eh? dime 00:24:02
Sí, es que lo he quitado a propósito 00:24:03
Para que, por si alguien 00:24:06
Yo que sé, para ir recordando cosas 00:24:08
Vale, entonces 00:24:10
Aquí acordaos 00:24:12
De que cuando a Java 00:24:14
Le dais un número sin más 00:24:15
Él automáticamente lo interpreta 00:24:18
Como int y lo guarda en variable de 32 bits 00:24:20
Lo guarda como int 00:24:23
Aquí, él me está diciendo 00:24:24
Perdona, me estás dando un tipo i 00:24:27
Para un método que necesita un tipo long 00:24:29
Entonces no le gusta 00:24:31
¿Cómo forzamos a que Java 00:24:32
Un numerito te lo guarde en 64 bits 00:24:35
En lugar de 32? 00:24:38
Pues le forzábamos poniéndole 00:24:40
La L después 00:24:42
¿Pero esto lo tenías en mayúsculas? 00:24:43
¿Para el envolvente dentro? 00:24:45
No, no, no 00:24:49
Lo tenía en mayúsculas 00:24:49
Porque yo lo veo más claro en mayúsculas 00:24:51
Porque esto parece 31-21 00:24:53
De hecho lo he puesto a propósito 00:24:54
Para que veáis lo feo que queda 00:24:56
Entonces en un código 00:24:59
lo natural sería ponerlo en mayúscula 00:25:01
por no confundirlo con el dígito 00:25:04
funciona igual porque el código ASCII es el de la L 00:25:07
no es el del 1 00:25:11
entonces lo que está realmente codificado es 00:25:11
la L, no el 1, dime 00:25:14
¿el JPA útil de dónde sale? 00:25:15
del otro proyecto 00:25:19
ya lo tenemos hecho, lo copias y pegas 00:25:20
el JPA útil, ya lo hicimos 00:25:22
es una clase que nos 00:25:24
era una utilidad 00:25:26
para crear a través de este método 00:25:27
Un entity manager cada vez que lo quisiéramos 00:25:30
Cada vez uno nuevo 00:25:33
Porque no es un singleton 00:25:34
El que es el singleton es este 00:25:35
Entonces del otro proyecto que hicimos lo copias y ya está 00:25:37
¿Vale? Entonces 00:25:40
Primero es que funcione 00:25:45
Porque ya hemos puesto las anotaciones bien 00:25:48
Y luego es si elimina 00:25:49
Vamos a ver 00:25:52
Deletes no ha hecho 00:25:53
Con lo cual es imposible que lo haya borrado 00:26:04
¿Vale? 00:26:07
Vale 00:26:09
Entonces, ¿cuál ha sido aquí el problema? 00:26:09
No ha sido que nuestro equals, el remove, ¿no? 00:26:14
Si esto está estupendo 00:26:18
No ha sido el remove 00:26:19
El problema es lo que os he dicho al principio 00:26:21
Que estamos borrando a través de quien no es propietaria 00:26:24
Estamos borrando a través de jugador 00:26:29
Jugador no es la propietaria 00:26:32
Jugador tiene el extremo 00:26:34
aquí 00:26:37
este 00:26:39
entonces ese borrado no se va a hacer 00:26:41
¿vale? ese borrado no se va a hacer 00:26:44
la que manda es esta otra 00:26:46
entonces 00:26:48
¿qué otra forma 00:26:50
podríamos hacer? 00:26:52
y veréis que rollo, por eso tenemos que poner solución 00:26:54
a este rollo 00:26:56
¿dónde estamos? aquí en servicios 00:26:58
vale 00:27:00
pues 00:27:00
¿vale? 00:27:02
La solución 00:27:06
Mejor entre comillas 00:27:13
Hacerlo con una delete 00:27:15
Lo podemos hacer todo siempre con una delete 00:27:16
Y ya está 00:27:20
Hacer una query que borre 00:27:20
Delete from videojuego 00:27:23
Where jv no se que 00:27:25
Hacer una jpql delete 00:27:27
Y ya está 00:27:29
Hacemos una query 00:27:30
Y le pedimos 00:27:31
Y la otra 00:27:34
Esto de aquí 00:27:36
Vale 00:27:37
la otra, vamos a 00:27:43
quedarnos, en lugar 00:27:45
de borrar, ¿dónde estoy? aquí 00:27:47
aquí 00:27:49
en lugar de borrar 00:27:51
a este elemento 00:27:53
a través de J 00:27:55
que no puedo, porque J no es el propietario 00:27:59
voy a sacarme 00:28:01
el elemento y le voy a hacer el remove a él directamente 00:28:03
voy a sacármelo de aquí 00:28:05
de esta conexión 00:28:07
voy a sacarme el elemento y le voy a hacer 00:28:09
Entonces, esto 00:28:11
Pues lo podríamos hacer 00:28:13
Jugador de videojuegos 00:28:15
¿Vale? Vamos a filtrar 00:28:18
A quedarnos con el bueno 00:28:19
Vamos a hacerlo más bonito 00:28:20
¿Vale? 00:28:29
Que os gusta más así 00:28:33
¿Aquí qué tenemos que hacer? 00:28:34
Pues un filter, lógicamente 00:28:38
Vamos a quedarnos 00:28:39
De cada elemento de la lista 00:28:42
Nos vamos a quedar 00:28:44
Solamente con aquel 00:28:46
Que sea igual 00:28:49
A este 00:29:02
¿Vale? 00:29:04
Lo que dices tú de get 00:29:07
Directamente no puedes, eso lo podrías hacer con un diccionario 00:29:08
Con un mapa, con esto no, tienes que hacer un recorrido 00:29:10
Entonces ese recorrido lo agarramos con el stream 00:29:12
Vale, entonces me quedo 00:29:15
Con aquel que sea igual a JV 00:29:16
Que entendemos que es solamente uno 00:29:19
Con lo cual 00:29:22
Le cojo 00:29:23
Y como es un optional 00:29:25
Cogemos a lo bestia 00:29:26
Ni orel directamente get 00:29:29
Si me da nul, me da nul 00:29:31
Si es que nosotros estamos por encima de los nules 00:29:32
Vale 00:29:35
Y aquí ya la puedo coger 00:29:36
Jugador 00:29:38
Videojuego 00:29:39
Jugador 00:29:43
Esta es la que quiero borrar 00:29:45
sí, sí, sí, esto es que no va a hacer nada 00:29:47
pero tienes razón 00:29:57
que es buena idea quitarlo 00:30:00
porque esto no va a hacer nada cuando se vaya a sincronizar 00:30:01
pero los objetos 00:30:03
dentro del contexto de persistencia se quedan marcados 00:30:05
con marcas, este en particular se queda 00:30:08
que en la colección este ya no está 00:30:09
con lo cual este nos daría que no lo encuentre 00:30:11
entonces sería un problema 00:30:14
efectivamente, si yo no lo llego a quitar 00:30:16
que es que se me había olvidado, me habría dado cuenta al ejecutarlo 00:30:17
pero 00:30:20
de que no hace nada 00:30:21
y es porque lo hemos quitado de la colección 00:30:22
entonces este filter 00:30:25
no lo encontraría 00:30:27
entonces, ahora ya 00:30:28
este de aquí es el objeto persistente 00:30:31
que hemos sacado de aquí, y este como es persistente 00:30:33
le aplica 00:30:36
esto si a mí me da la gana, perdón 00:30:37
el remove 00:30:39
remove, borrar 00:30:39
¿vale? o sea 00:30:43
este def lo hemos podido hacer 00:30:53
sin problemas, porque 00:30:56
estamos en el contexto 00:30:58
de una transacción 00:31:00
por muy lazy que sea 00:31:01
que será lazy 00:31:03
si no lo hemos puesto por 00:31:04
supongo que lo habremos puesto 00:31:06
y si no será por defecto 00:31:09
donde está jugador 00:31:10
jugador 00:31:13
aquí 00:31:14
no lo hemos puesto el fetch type 00:31:17
por lo cual será lazy que es algo por defecto 00:31:20
entonces por muy lazy que sea 00:31:22
si pero esta es la otra 00:31:25
esta es la otra 00:31:31
porque esta por defecto si que es eager 00:31:32
las many to one por defecto si que son eager 00:31:34
por eso es así 00:31:36
la hemos puesto específica 00:31:37
por defecto para eso 00:31:39
Iger 00:31:40
porque esta no pesa tanto 00:31:42
porque es solo un objeto 00:31:44
el que recupera 00:31:45
sin embargo este 00:31:46
recupera una lista entera 00:31:46
entonces este sí que pesa más 00:31:47
por eso por defecto es lazy 00:31:49
pues bueno 00:31:50
por muy lazy que sea 00:31:50
que lo es 00:31:52
aquí estamos en el contexto 00:31:53
de una transacción 00:31:55
entonces 00:31:56
este get de aquí 00:31:57
no da un 00:31:59
¿vale? 00:32:00
sin embargo 00:32:01
si estuviéramos con sprint data 00:32:02
esto nos daría un lazy 00:32:04
exception, un segundín, que te cagas 00:32:07
¿por qué? porque el gestor de las 00:32:10
transacciones como le da la gana 00:32:11
entonces nosotros tenemos que preocuparnos y decirle 00:32:13
uy, cuidado, cuidado 00:32:15
y anotarlo, anotarlo 00:32:16
para que la gestione como queremos nosotros 00:32:19
¿vale? entonces 00:32:21
digo simplemente que no es que Sprint te lo haga todo 00:32:22
te lo hace todo si lo anotas bien 00:32:25
¿vale? dime 00:32:26
Sí, sí, sí, es lo que he dicho al principio 00:32:29
que vamos a puentear el DAO 00:32:40
para no escribir, o sea, esta aplicación 00:32:42
que estamos de aquí 00:32:44
¿vale? Tendría que tener 00:32:46
su capa de DAO con los cuatro 00:32:48
métodos básicos, pero claro, para no 00:32:50
eternizarnos haciendo esto, me interesa lo de JPA 00:32:52
por eso he dicho, vamos a puentear 00:32:55
el DAO y que el servicio 00:32:56
llame directamente a los métodos de 00:32:58
NC Manager 00:33:00
Sí, bueno, a ver, podemos copiar y pegar 00:33:01
aquí el generic DAO 00:33:14
si te angustia 00:33:16
que no haya una capa DAO, o sea, la estoy puenteando 00:33:18
o sea, avisado a sabiendas de que no 00:33:20
trabajamos así, porque lo que estamos ahora 00:33:22
un poco escenificando 00:33:24
según el JPA, entonces para no 00:33:26
meterle la complicación del dao entre medias 00:33:28
pero que si hacemos un genérico es meter 00:33:30
una clase más y luego hay que instanciar un dao 00:33:32
con el jugador 00:33:34
que sea, jugador videojuego dao 00:33:36
vale 00:33:38
si yo en un dao tengo operaciones 00:33:38
más complejas, ahí lo voy a meter 00:33:42
en el dao, pero en el modo create 00:33:44
o en el modo rotate 00:33:46
get 00:33:47
en esos 00:33:52
al final el end 00:33:55
el entity manager y el DAO genérico 00:33:57
hacen lo mismo 00:34:00
sí, sí, sí, o sea el DAO 00:34:01
lo que hace es el persist, o sea el create 00:34:04
hace persist, el get hace find 00:34:06
sí, sí, sí, pero bueno 00:34:08
depende en qué contexto me hablas 00:34:10
si me hablas en contexto de nosotros en clase 00:34:14
para el examen o me hablas en contexto 00:34:16
del mundo 00:34:18
normalmente en los proyectos amplios 00:34:19
pues el DAO tiene muchos más métodos 00:34:22
que los básicos 00:34:24
tiene métodos de recuperar por otro campo 00:34:26
tiene cosas, entonces 00:34:29
sí que habrá DAO 00:34:30
Claro, que tengas un DAO por cada clase 00:34:31
También, sí 00:34:36
Sí, te refieres 00:34:38
que hacer el genérico queda un poco igual 00:34:42
que puedes, si vas a hacer 00:34:44
un DAO por cada entidad, pues ya 00:34:46
en ese metes lo del genérico 00:34:48
y lo implementas 00:34:50
Sí, sí, yo lo de meter el genérico en el otro 00:34:51
era para que no se os olvidara 00:34:54
para que no se os olvidaran 00:34:56
los tipos de genéricos 00:34:59
como se usan y también 00:35:01
para aprovechar, para meterlo 00:35:02
recordarlo del punto class, pues que es 00:35:04
el punto class que es un 00:35:06
objeto que describe una clase 00:35:08
etcétera, vale 00:35:10
aunque luego efectivamente una vez metido se quedan 00:35:12
cuatro métodos que tienen una línea dentro 00:35:14
cada uno de ellos, vale 00:35:16
vale, vamos a parar un segundín 00:35:18
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Segundo Curso
Subido por:
Raquel G.
Licencia:
Todos los derechos reservados
Visualizaciones:
5
Fecha:
1 de febrero de 2026 - 19:06
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
35′ 22″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
159.26 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid