Procesado con Transacción por película

This commit is contained in:
Isidoro Nevares Martín 2026-01-09 15:14:13 +01:00
parent 183c90e13b
commit 3898df1d77
12 changed files with 211 additions and 113 deletions

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -9,7 +9,7 @@ import org.lapaloma.aadd.cine.dao.hbnt.ContinenteDaoHibernate;
import org.lapaloma.aadd.cine.dao.hbnt.DirectorDaoHibernate; import org.lapaloma.aadd.cine.dao.hbnt.DirectorDaoHibernate;
import org.lapaloma.aadd.cine.dao.hbnt.PaisDaoHibernate; import org.lapaloma.aadd.cine.dao.hbnt.PaisDaoHibernate;
import org.lapaloma.aadd.cine.dao.hbnt.PeliculaDaoHibernate; import org.lapaloma.aadd.cine.dao.hbnt.PeliculaDaoHibernate;
import org.lapaloma.aadd.cine.gestores.GestorFicheroConfiguracion; import org.lapaloma.aadd.cine.procesos.ProcesadorPeliculasJSON;
import org.lapaloma.aadd.cine.servicio.ActorService; import org.lapaloma.aadd.cine.servicio.ActorService;
import org.lapaloma.aadd.cine.servicio.ContinenteService; import org.lapaloma.aadd.cine.servicio.ContinenteService;
import org.lapaloma.aadd.cine.servicio.DirectorService; import org.lapaloma.aadd.cine.servicio.DirectorService;
@ -40,8 +40,20 @@ public class AppCine {
} }
private void procesarFicheroJSON() { private void procesarFicheroJSON() {
org.lapaloma.aadd.cine.procesos.ProcesadorPeliculasJSON procesador = new org.lapaloma.aadd.cine.procesos.ProcesadorPeliculasJSON(); ProcesadorPeliculasJSON procesador = new ProcesadorPeliculasJSON();
procesador.procesar(); procesador.procesarFicheroInformacionFestival();
/*
probarOperacionesContinente();
probarOperacionesPais();
probarOperacionesDirector();
probarOperacionesPelicula();
probarOperacionesActor();
*/
} }
private void probarOperacionesContinente() { private void probarOperacionesContinente() {

View File

@ -10,4 +10,9 @@ public interface IActorDAO extends IOperacionesDAOEntidad<Actor, Integer> {
void borrarActoresReferenciasContinente(String codigoContinente) throws Exception; void borrarActoresReferenciasContinente(String codigoContinente) throws Exception;
Actor obtenerActorPorNombre(String nombre); Actor obtenerActorPorNombre(String nombre);
void actualizarActor(Actor actor) throws Exception;
void insertarActor(Actor actor) throws Exception;
} }

View File

@ -10,4 +10,8 @@ public interface IDirectorDAO extends IOperacionesDAOEntidad<Director, Integer>
void borrarDirectoresReferenciasContinente(String codigoContinente) throws Exception; void borrarDirectoresReferenciasContinente(String codigoContinente) throws Exception;
Director obtenerDirectorPorNombre(String nombre); Director obtenerDirectorPorNombre(String nombre);
void actualizarDirector(Director director) throws Exception;
void insertarDirector(Director director) throws Exception;
} }

View File

@ -11,5 +11,9 @@ public interface IPeliculaDAO extends IOperacionesDAOEntidad<Pelicula, Integer>
void borrarPeliculasReferenciasContinente(String codigoContinente) throws Exception; void borrarPeliculasReferenciasContinente(String codigoContinente) throws Exception;
Pelicula obtenerPeliculaPorTituloYAnyo(String titulo, Integer anyo); Pelicula obtenerPeliculaPorTitulo(String titulo) throws Exception;
void actualizarPelicula(Pelicula pelicula) throws Exception;
void insertarPelicula(Pelicula pelicula) throws Exception;
} }

View File

@ -13,4 +13,8 @@ public interface IRepartoDAO extends IOperacionesDAOEntidad<Reparto, RepartoId>
void borrarRepartoReferenciasPais(Integer idPais) throws Exception; void borrarRepartoReferenciasPais(Integer idPais) throws Exception;
void borrarRepartoReferenciasContinente(String codigoContinente) throws Exception; void borrarRepartoReferenciasContinente(String codigoContinente) throws Exception;
void insertarReparto(Reparto reparto) throws Exception;
void actualizarReparto(Reparto reparto) throws Exception;
} }

View File

@ -176,4 +176,16 @@ public class ActorDaoHibernate implements IActorDAO {
return actor; return actor;
} }
@Override
public void actualizarActor(Actor actor) throws Exception {
Session sesion = GestorSesionesHibernate.getCurrentSession();
sesion.merge(actor);
}
@Override
public void insertarActor(Actor actor) throws Exception {
Session sesion = GestorSesionesHibernate.getCurrentSession();
sesion.persist(actor);
}
} }

View File

@ -175,4 +175,16 @@ public class DirectorDaoHibernate implements IDirectorDAO {
return director; return director;
} }
@Override
public void actualizarDirector(Director director) throws Exception {
Session sesion = GestorSesionesHibernate.getCurrentSession();
sesion.merge(director);
}
@Override
public void insertarDirector(Director director) throws Exception {
Session sesion = GestorSesionesHibernate.getCurrentSession();
sesion.persist(director);
}
} }

View File

@ -186,13 +186,12 @@ public class PeliculaDaoHibernate implements IPeliculaDAO {
} }
@Override @Override
public Pelicula obtenerPeliculaPorTituloYAnyo(String titulo, Integer anyo) { public Pelicula obtenerPeliculaPorTitulo(String titulo) {
Pelicula pelicula = null; Pelicula pelicula = null;
String sentenciaHQL = "SELECT p FROM Pelicula p WHERE p.titulo = :titulo AND p.anyo = :anyo"; String sentenciaHQL = "SELECT p FROM Pelicula p WHERE p.titulo = :titulo";
try (Session sesion = GestorSesionesHibernate.getSession();) { try (Session sesion = GestorSesionesHibernate.getSession();) {
SelectionQuery<Pelicula> sentenciaConsulta = sesion.createSelectionQuery(sentenciaHQL, Pelicula.class); SelectionQuery<Pelicula> sentenciaConsulta = sesion.createSelectionQuery(sentenciaHQL, Pelicula.class);
sentenciaConsulta.setParameter("titulo", titulo); sentenciaConsulta.setParameter("titulo", titulo);
sentenciaConsulta.setParameter("anyo", anyo);
pelicula = sentenciaConsulta.getSingleResultOrNull(); pelicula = sentenciaConsulta.getSingleResultOrNull();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -200,4 +199,16 @@ public class PeliculaDaoHibernate implements IPeliculaDAO {
return pelicula; return pelicula;
} }
@Override
public void actualizarPelicula(Pelicula pelicula) throws Exception {
Session sesion = GestorSesionesHibernate.getCurrentSession();
sesion.merge(pelicula);
}
@Override
public void insertarPelicula(Pelicula pelicula) throws Exception {
Session sesion = GestorSesionesHibernate.getCurrentSession();
sesion.persist(pelicula);
}
} }

View File

@ -182,4 +182,16 @@ public class RepartoDaoHibernate implements IRepartoDAO {
} }
@Override
public void insertarReparto(Reparto reparto) throws Exception {
Session sesion = GestorSesionesHibernate.getCurrentSession();
sesion.persist(reparto);
}
@Override
public void actualizarReparto(Reparto reparto) throws Exception {
Session sesion = GestorSesionesHibernate.getCurrentSession();
sesion.merge(reparto);
}
} }

View File

@ -15,6 +15,7 @@ import org.lapaloma.aadd.cine.dao.hbnt.DirectorDaoHibernate;
import org.lapaloma.aadd.cine.dao.hbnt.PaisDaoHibernate; import org.lapaloma.aadd.cine.dao.hbnt.PaisDaoHibernate;
import org.lapaloma.aadd.cine.dao.hbnt.PeliculaDaoHibernate; import org.lapaloma.aadd.cine.dao.hbnt.PeliculaDaoHibernate;
import org.lapaloma.aadd.cine.dao.hbnt.RepartoDaoHibernate; import org.lapaloma.aadd.cine.dao.hbnt.RepartoDaoHibernate;
import org.lapaloma.aadd.cine.gestores.GestorFicheroConfiguracion;
import org.lapaloma.aadd.cine.gestores.GestorSesionesHibernate; import org.lapaloma.aadd.cine.gestores.GestorSesionesHibernate;
import org.lapaloma.aadd.cine.vo.Actor; import org.lapaloma.aadd.cine.vo.Actor;
import org.lapaloma.aadd.cine.vo.Director; import org.lapaloma.aadd.cine.vo.Director;
@ -34,89 +35,83 @@ public class ProcesadorPeliculasJSON {
private IPaisDAO paisDAO = new PaisDaoHibernate(); private IPaisDAO paisDAO = new PaisDaoHibernate();
private IRepartoDAO repartoDAO = new RepartoDaoHibernate(); private IRepartoDAO repartoDAO = new RepartoDaoHibernate();
public void procesar() { public void procesarFicheroInformacionFestival() {
File fichero = new File("ficheros/peliculas-festival.json"); String rutaFichero = GestorFicheroConfiguracion.getValorfromClave("festival.fichero.json.ruta");
File fichero = new File(rutaFichero);
// Se asume que la información de Paises es correcta y ya existe en la BD
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(fichero); JsonNode root = mapper.readTree(fichero);
JsonNode peliculasNode = root.get("peliculas"); JsonNode nodoPeliculas = root.get("peliculas");
if (peliculasNode != null && peliculasNode.isArray()) { // Procesar cada película enviada por el festival
for (JsonNode peliculaNode : peliculasNode) { if (nodoPeliculas != null && nodoPeliculas.isArray()) {
procesarPelicula(peliculaNode); for (JsonNode nodoPelicula : nodoPeliculas) {
procesarPelicula(nodoPelicula);
} }
} }
} }
private void procesarPelicula(JsonNode node) { private void procesarPelicula(JsonNode nodoPelicula) {
Transaction transaccion = null; Transaction transaccion = null;
// Usamos getCurrentSession para que todos los DAO usen la misma sesión y // Usamos getCurrentSession para que todos los DAO usen la misma sesión y
// transacción // transacción
try (Session sesion = GestorSesionesHibernate.getCurrentSession()) { try (Session sesion = GestorSesionesHibernate.getSession()) {
// Iniciar transacción
transaccion = sesion.beginTransaction(); transaccion = sesion.beginTransaction();
// 1. Obtener Pais de Localización // 1. Procesar Director Pelicula
Integer idPais = node.get("pais").asInt(); JsonNode nodoDirector = nodoPelicula.get("director");
Director director = obtenerDirectorTrasProcesarlo(nodoDirector);
// 2. Procesar Película
String titulo = nodoPelicula.get("titulo").asString();
Pelicula pelicula = peliculaDAO.obtenerPeliculaPorTitulo(titulo);
String observacionJSON = nodoPelicula.get("observ").asString();
// Obtener Pais de Localización (se asume que existe)
Integer idPais = nodoPelicula.get("pais").asInt();
Pais paisLocalizacion = paisDAO.obtenerEntidadPorClave(idPais); Pais paisLocalizacion = paisDAO.obtenerEntidadPorClave(idPais);
// Si no existe el país lo podríamos crear, pero el enunciado dice "En caso de
// que no exista alguna de las entidades involucradas... habrá que
// almacenarlas".
// Sin embargo, para un país sólo tenemos el ID en este punto. Supongamos que el
// país debe existir o se crea uno básico si no existe (aunque faltarían datos).
// Por ahora nos centramos en Director, Actor y Película que tienen más datos.
if (paisLocalizacion == null) {
paisLocalizacion = new Pais();
paisLocalizacion.setIdentificador(idPais);
paisLocalizacion.setNombrePais("País desconocido (" + idPais + ")");
// El continente es obligatorio? En el VO no parece marcarse como nullable=false
// pero es una buena práctica.
// Para simplificar, si no existe el país básico, lo persistimos si fuera
// necesario.
// sesion.persist(paisLocalizacion);
}
// 2. Procesar Director String idioma = nodoPelicula.get("idioma").asString();
JsonNode directorNode = node.get("director"); boolean color = nodoPelicula.get("color").asBoolean();
String nombreDirector = directorNode.get("nombre").asString();
Director director = directorDAO.obtenerDirectorPorNombre(nombreDirector);
if (director == null) {
director = new Director();
director.setNombre(nombreDirector);
fillDirectorInfo(director, directorNode);
sesion.persist(director);
} else {
fillDirectorInfo(director, directorNode);
sesion.merge(director);
}
// 3. Procesar Película
String titulo = node.get("titulo").asString();
Integer anyo = node.get("anyo").asInt();
Pelicula pelicula = peliculaDAO.obtenerPeliculaPorTituloYAnyo(titulo, anyo);
String observacionJSON = node.get("observ").asString();
// Si la película no existe se crea nueva, si no se actualiza
if (pelicula == null) { if (pelicula == null) {
pelicula = new Pelicula(); pelicula = new Pelicula();
pelicula.setTitulo(titulo); pelicula.setTitulo(titulo);
pelicula.setAnyo(anyo); pelicula.setPaisLocalizacion(paisLocalizacion);
fillPeliculaInfo(pelicula, node, paisLocalizacion, director); pelicula.setDirector(director);
pelicula.setIdioma(idioma);
pelicula.setColor(color);
pelicula.setObservacion(observacionJSON); pelicula.setObservacion(observacionJSON);
sesion.persist(pelicula);
peliculaDAO.insertarPelicula(pelicula);
} else { } else {
pelicula.setTitulo(titulo);
pelicula.setPaisLocalizacion(paisLocalizacion);
pelicula.setDirector(director);
pelicula.setIdioma(idioma);
pelicula.setColor(color);
String obsActual = pelicula.getObservacion(); String obsActual = pelicula.getObservacion();
pelicula.setObservacion((obsActual != null ? obsActual : "") + observacionJSON); if (obsActual!=null && !obsActual.contains(observacionJSON)) {
fillPeliculaInfo(pelicula, node, paisLocalizacion, director); obsActual += obsActual + " | " + observacionJSON;
sesion.merge(pelicula); }else {
} obsActual = observacionJSON;
// 4. Procesar Reparto y Actores
JsonNode repartoNode = node.get("reparto");
if (repartoNode != null && repartoNode.isArray()) {
for (JsonNode actorNode : repartoNode) {
procesarActorYReparto(sesion, actorNode, pelicula);
} }
pelicula.setObservacion(obsActual.substring(0, 50)); // Limitar a 50 caracteres (de la BBDD)
peliculaDAO.actualizarPelicula(pelicula);
} }
// 3. Procesar Reparto (y sus actores)
JsonNode nodoReparto = nodoPelicula.get("reparto");
procesarActoresYReparto(nodoReparto, pelicula);
// Confirmar transacción
transaccion.commit(); transaccion.commit();
System.out.println("Procesada con éxito la película: " + titulo); System.out.println("Procesada con éxito la película: " + titulo);
} catch (Exception e) { } catch (Exception e) {
if (transaccion != null && transaccion.isActive()) { if (transaccion != null && transaccion.isActive()) {
@ -127,64 +122,89 @@ public class ProcesadorPeliculasJSON {
} }
} }
private void fillDirectorInfo(Director director, JsonNode node) { private Director obtenerDirectorTrasProcesarlo(JsonNode nodoDirector) throws Exception {
if (node.has("fechaNacimiento")) { String nombreDirector = nodoDirector.get("nombre").asString();
director.setFechaNacimiento(LocalDate.parse(node.get("fechaNacimiento").asString())); Director director = null;
LocalDate fechaNacimiento = null;
Pais paisNacimiento = null;
if (nodoDirector.has("fechaNacimiento")) {
fechaNacimiento = LocalDate.parse(nodoDirector.get("fechaNacimiento").asString());
} }
if (node.has("pais")) { if (nodoDirector.has("pais")) {
Integer idPais = node.get("pais").asInt(); Integer idPais = nodoDirector.get("pais").asInt();
Pais p = paisDAO.obtenerEntidadPorClave(idPais); paisNacimiento = paisDAO.obtenerEntidadPorClave(idPais);
if (p != null) { }
director.setPais(p); director = directorDAO.obtenerDirectorPorNombre(nombreDirector);
// Si no existe, crear nuevo Director
if (director == null) {
director = new Director();
director.setNombre(nombreDirector);
director.setFechaNacimiento(fechaNacimiento);
director.setPais(paisNacimiento);
directorDAO.insertarDirector(director);
} else {
director.setNombre(nombreDirector);
if (fechaNacimiento != null)
director.setFechaNacimiento(fechaNacimiento);
if (paisNacimiento != null)
director.setPais(paisNacimiento);
directorDAO.actualizarDirector(director);
}
return director;
}
private void procesarActoresYReparto(JsonNode nodoReparto, Pelicula pelicula) throws Exception {
if (nodoReparto != null && nodoReparto.isArray()) {
for (JsonNode nodoActorPeli : nodoReparto) {
// Procesar Actor
Actor actor = obtenerActorTrasProcesarlo(nodoActorPeli);
// Procesar Reparto
String personaje = nodoActorPeli.get("personaje").asString();
RepartoId idReparto = new RepartoId(actor.getIdentificador(), pelicula.getIdentificador());
Reparto reparto = repartoDAO.obtenerEntidadPorClave(idReparto);
if (reparto == null) {
reparto = new Reparto();
reparto.setIdReparto(idReparto);
reparto.setActor(actor);
reparto.setPelicula(pelicula);
reparto.setPersonaje(personaje);
repartoDAO.insertarReparto(reparto);
} else {
reparto.setPersonaje(personaje);
repartoDAO.actualizarReparto(reparto);
}
} }
} }
} }
private void fillPeliculaInfo(Pelicula pelicula, JsonNode node, Pais pais, Director director) { private Actor obtenerActorTrasProcesarlo(JsonNode nodoActor) throws Exception {
pelicula.setIdioma(node.get("idioma").asString()); Actor actor = null;
pelicula.setColor(node.get("color").asBoolean());
pelicula.setPaisLocalizacion(pais);
pelicula.setDirector(director);
}
private void procesarActorYReparto(Session sesion, JsonNode node, Pelicula pelicula) { String nombreActor = nodoActor.get("nombre").asString();
String nombreActor = node.get("nombre").asString(); actor = actorDAO.obtenerActorPorNombre(nombreActor);
Actor actor = actorDAO.obtenerActorPorNombre(nombreActor);
Integer idPais = nodoActor.get("pais").asInt();
Pais paisActor = paisDAO.obtenerEntidadPorClave(idPais);
// Si no existe, crear nuevo Actor en caso contrario actualizar país
if (actor == null) { if (actor == null) {
actor = new Actor(); actor = new Actor();
actor.setNombre(nombreActor); actor.setNombre(nombreActor);
fillActorInfo(actor, node); actor.setPais(paisActor);
sesion.persist(actor);
} else {
fillActorInfo(actor, node);
sesion.merge(actor);
}
String personaje = node.get("personaje").asString(); actorDAO.insertarActor(actor);
RepartoId idReparto = new RepartoId(actor.getIdentificador(), pelicula.getIdentificador());
Reparto reparto = sesion.find(Reparto.class, idReparto);
if (reparto == null) {
reparto = new Reparto();
reparto.setIdReparto(idReparto);
reparto.setActor(actor);
reparto.setPelicula(pelicula);
reparto.setPersonaje(personaje);
sesion.persist(reparto);
} else { } else {
reparto.setPersonaje(personaje); actor.setPais(paisActor);
sesion.merge(reparto); actorDAO.actualizarActor(actor);
} }
return actor;
} }
private void fillActorInfo(Actor actor, JsonNode node) {
if (node.has("pais")) {
Integer idPais = node.get("pais").asInt();
Pais p = paisDAO.obtenerEntidadPorClave(idPais);
if (p != null) {
actor.setPais(p);
}
}
}
} }

View File

@ -1,4 +1,4 @@
# Información sobre fichero JSON # Información sobre fichero JSON
cine.fichero.json.ruta=ficheros/peliculas-festival.json festival.fichero.json.ruta=ficheros/peliculas-festival.json