Buscar
Social
Ofertas laborales ES

Foro sobre Java EE > JPA Controladores de Entidades Relacionadas

[Nota: Se movió la pregunta desde el foro JavaSE para acá]

Buenas tengo el siguiente problema cuando intento borrar un registro de la bd.

la base de datos se compone de dos tablas

Departamentos
Empleados

estan relacionadas 1:N con un restricción en la clave foranea en cascada para actualizaciones y borrados...si borro un departamento se borran los registros empleados que pertenecen a ese departamento..

aqui el script SQL

DROP SCHEMA IF EXISTS `empresabd` ;
CREATE SCHEMA IF NOT EXISTS `empresabd` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `empresabd` ;

-- -----------------------------------------------------
-- Table `empresabd`.`departamentos`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `empresabd`.`departamentos` ;

CREATE TABLE IF NOT EXISTS `empresabd`.`departamentos` (
`iddep` INT NOT NULL AUTO_INCREMENT ,
`categoria` VARCHAR(45) NOT NULL ,
`descripcion` VARCHAR(200) NOT NULL ,
PRIMARY KEY (`iddep`) )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `empresabd`.`empleados`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `empresabd`.`empleados` ;

CREATE TABLE IF NOT EXISTS `empresabd`.`empleados` (
`dni` VARCHAR(10) NOT NULL ,
`nombre` VARCHAR(40) NOT NULL ,
`apellidos` VARCHAR(150) NOT NULL ,
`direccion` VARCHAR(200) NOT NULL ,
`tel` VARCHAR(10) NOT NULL ,
`iddep` INT NOT NULL ,
PRIMARY KEY (`dni`) ,
INDEX `fk_empleados_departamentos` (`iddep` ASC) ,
CONSTRAINT `fk_empleados_departamentos`
FOREIGN KEY (`iddep` )
REFERENCES `empresabd`.`departamentos` (`iddep` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

CREATE USER 'userempresabd'@'localhost' IDENTIFIED BY '123';
GRANT SELECT ,
INSERT ,
UPDATE ,
DELETE ON `empresabd` . * TO 'userempresabd'@'localhost';

INSERT INTO departamentos (categoria, descripcion) VALUES
('1a', 'RECURSOS HUMANOS'),
('1b', 'ID+D');

INSERT INTO empleados (dni, nombre, apellidos, direccion, tel, iddep) VALUES
('11111111D', 'Pablo', 'Arjona', 'Calle 2', '000111222', '1'),
('22222222D', 'Ana', 'Arjone', 'Calle 3', '000222333', '2');

en netbeans genero las clases entidad a partir de la base de datos:

Clase entidad Departamentos
Clase entidad Empleados

También genero las clases controller de las clases entidad con netbeans.. que lo hace al vuelo

Hago una insercion y un update usando los metodos de las clases controladoras sin problema pero al probar hacer un borrado de un departamento no me deja si hay algun empleado en ese departamento.. me lanza un IllegalOrphanException

no se si tengo que modificar los metodos que me genera netbeans o no.

el codigo del main es el siguiente:

public class Main {

public static void main(String args[]) {
//inicializamos el EntityManagerFactory
EntityManagerFactory emf = Persistence.createEntityManagerFactory("empresaPU");

// instanciamos objetos de las clase controladora Departamentos
DepartamentosJpaController controlD = new DepartamentosJpaController(emf);
EmpleadosJpaController controlE = new EmpleadosJpaController(emf);
try {
// utilizamos el metodo destroy para eliminar el departamento
// al metodo solo le pasamos el id del departamento
// Este método bucará por la propiedad id el registro
// en el base de datos para persistir los cambios
controlD.destroy(2);
} catch (IllegalOrphanException | NonexistentEntityException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

}
}

me lanza esta excepción

Controladores.exceptions.IllegalOrphanException: This Departamentos (Entidades.Departamentos[ iddep=2 ]) cannot be destroyed since the Empleados Entidades.Empleados[ dni=22222222D ] in its empleadosCollection field has a non-nullable iddep field.

no lo entiendo se supone que netbeans tendria que generar los metodos para que pudiese borrar un departamento y automaticamente cualquier empleado de ese departamento sin tener que modificarlo ....no entiendo esa IllegalOrphanException!!

puedo solucionarlo modificando el metodo destroy del DepartamentosJpaController

public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
Departamentos departamentos;
try {
departamentos = em.getReference(Departamentos.class, id);
departamentos.getIddep();
} catch (EntityNotFoundException enfe) {
throw new NonexistentEntityException("The departamentos with id " + id + " no longer exists.", enfe);
}
List<String> illegalOrphanMessages = null;
Collection<Empleados> empleadosCollectionOrphanCheck = departamentos.getEmpleadosCollection();
for (Empleados empleadosCollectionOrphanCheckEmpleados : empleadosCollectionOrphanCheck) {
em.remove(empleadosCollectionOrphanCheckEmpleados);
// if (illegalOrphanMessages == null) {
// illegalOrphanMessages = new ArrayList<String>();
// }
// illegalOrphanMessages.add("This Departamentos (" + departamentos + ") cannot be destroyed since the Empleados " + empleadosCollectionOrphanCheckEmpleados + " in its empleadosCollection field has a non-nullable iddep field.");
}
// if (illegalOrphanMessages != null) {
// throw new IllegalOrphanException(illegalOrphanMessages);
// }
em.remove(departamentos);
em.getTransaction().commit();
} finally {
if (em != null) {
em.close();
}
}
}

pero en dos tablas se hace rapido ...pero teniendo muuuchas tablas y muuchas relaciones de ese tipo la cosa se hace tediosa...no entiendo porque el método me lanza la excepción en vez de borrar el departamento y los empleados de este departamento..

se supone que la herramienta que tiene netbeans que genera las clases controller de las clases entidad agiliza la tarea y no la hace mas tediosa. alguna sugerencia?

febrero 8, 2013 | Registered Commenterpacosx10

Buenas, es normal que por defecto no te deje eliminar un departamento si tiene empleados. Lo que quieres hacer es un borrado en cascada. Echale un vistazo a este link:

http://www.objectdb.com/java/jpa/persistence/delete

Saludos

febrero 11, 2013 | Unregistered CommenterUnoPorAhi