20260129 JPA_11 - Contenido educativo
Ajuste de pantallaEl ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:
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
no
00:02:13
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
Sí
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
no
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
Uy
00:17:06
videojuego.class
00:17:10
id
00:17:17
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
1
00:25:06
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
E
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
Uy
00:28:49
Que sea igual
00:28:49
A
00:28:55
JV
00:28:57
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
en
00:35:20
- 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