MER: tengo una tabla llamada lugar_de_trabajo esta tabla tiene una relacion 1:N
con ella misma es algo asi
--------------------------
| lugar_de_trabajo |
--------------------------
| codigo (PK) |
| ubicado (FK) |
| nombre |
--------------------------
La PK se genera autoincremental desde el mapeo de hibernate, bueno hasta ahi no hay problema, ahora explico el problema. Sucede que este lugar de trabajo puede ser una FAENA o una MAQUINA (estos son CLASES en la implementacion). FAENA son cuando NO tienen (FK) osea ubicado es NULL y lo contrario para las MAQUINA es decir cuando ubicado tiene valor. Las clases serian algo asi:
-------------------------------------
| Faena
-------------------------------------
| int codigo;
| String nombre;
| List<Maquina> maq;
-------------------------------------
| gets and sets.....
-------------------------------------
-------------------------------
| Maquina
-------------------------------
| int codigo;
| String nombre;
| Faena faena;
-------------------------------
| gets and sets.....
-------------------------------
Al probarlo me he dado cuenta que al crear una FAENA y luego asignarle dos MAQUINA, al tratar de guardarlo me arroja error, de que se repite la PK. Esto se debe a que la primera MAQUINA toma el mismo codigo que la primera FAENA(para caso de la prueba era solo una faena y dos maquinas) y eso pasa por ser clases distintas y ocupar mapeos distintos.... es decir hibernate se encarga de buscar el valor mayor de la PK, en este caso codigo, y para settear el valor del codigo de la faena nueva, le suma 1 y lo mismo sucede al crear una maquina, por lo que crea el mismo codigo para ambos objetos. Finalmente la pregunta es posible solucionar esto o se debe de realizar de otra forma? cual?
adjunto los codigo y mapeos.
Clase MAQUINA
Código:
public class Maquina extends ConexionHibernate implements Serializable { private int codigo; private String nombre; private String tipo; private Faena ubicado; // CONSTRUCTORES public Maquina() { this.tipo="Maquina"; } public Maquina(String nombre) { this.nombre = nombre; this.tipo = "Maquina"; } public int getCodigo() { return codigo; } private void setCodigo(int codigo) { this.codigo = codigo; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getTipo() { return tipo; } private void setTipo(String tipo) { this.tipo = tipo; } public Faena getUbicado() { return ubicado; } public void setUbicado(Faena ubicado) { this.ubicado = ubicado; } public int save() { return super.save(this); } public Faena getUbicacion(int id) { return ((Faena) super.getElemento(id)); } public boolean update() { return update(this); } public boolean delete() { return super.delete(this); } }
Clase FAENA
Código:
Clase CONEXIONHIBERNATEpublic class Faena extends ConexionHibernate implements Serializable { private int codigo; private String nombre; private String tipo; private List<Maquina> maquinas = new LinkedList<Maquina>(); // CONSTRUCTORES public Faena() { this.tipo="Faena"; } public Faena(String nombre) { this.nombre = nombre; this.tipo="Faena"; } public int getCodigo() { return codigo; } private void setCodigo(int codigo) { this.codigo = codigo; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getTipo() { return tipo; } private void setTipo(String tipo) { this.tipo = tipo; } public void addMaquina(Maquina maq){ this.maquinas.add(maq); maq.setUbicado(this); } public List<Maquina> getMaquinas(){ return maquinas; } public void setMaquinas(List<Maquina> maquinas){ this.maquinas = maquinas; } public int save() { return super.save(this); } public boolean update() { return update(this); } public boolean delete() { return super.delete(this); } public Faena getFaena(int id) throws Exception { Faena f = (Faena)super.getElemento(id); if(f == null) throw new Exception("No Se Encontro Faena"); else if( !f.getTipo().equalsIgnoreCase("Faena") ) throw new Exception("No Es Faena El Codigo"); return f; } }
Código:
Mapeo Faenaclass ConexionHibernate { public static Session sesion; public static Transaction tx; public static void iniciaOperacion() throws HibernateException { sesion = HibernateUtil.getSessionFactory().openSession(); tx = sesion.beginTransaction(); } public void manejaExcepcion(HibernateException he) throws HibernateException { tx.rollback(); he.printStackTrace(); //throw new HibernateException("Ocurrió un error en la capa de acceso a datos", he); } public Object getElemento(int codigo) { Object obj = null; try { ConexionHibernate.iniciaOperacion(); obj = ConexionHibernate.sesion.get(this.getClass(), codigo); } finally { ConexionHibernate.sesion.close(); } return obj; } public int save(Object t) { long id = 0; try { ConexionHibernate.iniciaOperacion(); ConexionHibernate.sesion.saveOrUpdate(t); ConexionHibernate.tx.commit(); id = (Integer)ConexionHibernate.sesion.getIdentifier(t); //id = (Integer)ConexionHibernate.sesion.save(t); }catch(HibernateException he) { this.manejaExcepcion(he); throw he; }catch(Exception e) { e.printStackTrace(); } finally { ConexionHibernate.sesion.close(); } return (int)id; } public boolean update(Object t) { boolean ret = false; try { ConexionHibernate.iniciaOperacion(); ConexionHibernate.sesion.update(t); ConexionHibernate.tx.commit(); ret = true; }catch (HibernateException he) { this.manejaExcepcion(he); throw he; }finally { ConexionHibernate.sesion.close(); } return ret; } public boolean delete(Object t) { boolean ret = false; try { ConexionHibernate.iniciaOperacion(); ConexionHibernate.sesion.delete(t); ConexionHibernate.tx.commit(); ret=true; } catch (HibernateException he) { this.manejaExcepcion(he); throw he; }finally { ConexionHibernate.sesion.close(); } return ret; } }
Código:
Mapeo Maquina<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="ClasesBases.Faena" table="lugar_trabajo"> <id column="codigo" name="codigo"> <generator class="increment"/> </id> <property column="nombre" name="nombre" type="string"/> <property column="tipo" name="tipo" type="string"/> <list name="maquinas" lazy="false" cascade="none" > <key column="ubicado_codigo"/> <index column="codigo"/> <one-to-many class="ClasesBases.Maquina"/> </list> </class> </hibernate-mapping>
Código:
Disculpen lo extenso, pero trate de explicarme lo mejor posible. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="ClasesBases.Maquina" table="lugar_trabajo"> <id column="codigo" name="codigo"> <generator class="increment"/> </id> <property column="nombre" name="nombre" type="string"/> <property column="tipo" name="tipo" type="string"/> <many-to-one name="ubicado" column="ubicado_codigo" /> </class> </hibernate-mapping>