Hibernate: error in inserting in table with relation

0

For now, I'm working with these tables

CREATE SCHEMA IF NOT EXISTS 'pasteleria' DEFAULT CHARACTER SET utf8 ;
USE 'pasteleria' ;

-- -----------------------------------------------------
-- Table 'pasteleria'.'Perfiles'
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS 'pasteleria'.'Perfiles' (
  'id' INT NOT NULL AUTO_INCREMENT,
  'perfil' VARCHAR(20) NOT NULL,
  'descripcion' VARCHAR(255) NOT NULL,
  PRIMARY KEY ('id'))
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table 'pasteleria'.'Usuarios'
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS 'pasteleria'.'Usuarios' (
  'id' INT NOT NULL AUTO_INCREMENT,
  'id_perfil' INT NOT NULL,
  'nick' VARCHAR(45) NOT NULL,
  'pass' VARCHAR(45) NOT NULL,
  PRIMARY KEY ('id'),
  INDEX 'fk_perfil_idx' ('id_perfil' ASC),
  CONSTRAINT 'fk_perfil'
    FOREIGN KEY ('id_perfil')
    REFERENCES 'pasteleria'.'Perfiles' ('id')
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table 'pasteleria'.'Clientes'
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS 'pasteleria'.'Clientes' (
  'id' VARCHAR(11) NOT NULL,
  'id_usu' INT NOT NULL,
  'nombre' VARCHAR(45) NOT NULL,
  'apellido' VARCHAR(45) NOT NULL,
  PRIMARY KEY ('id'),
  INDEX 'fk_usuario_idx' ('id_usu' ASC),
  CONSTRAINT 'fk_usuario'
    FOREIGN KEY ('id_usu')
    REFERENCES 'pasteleria'.'Usuarios' ('id')
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table 'pasteleria'.'TCP'
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS 'pasteleria'.'TCP' (
  'id' INT NOT NULL AUTO_INCREMENT,
  'id_cliente' VARCHAR(11) NOT NULL,
  'total_sellos' INT NOT NULL DEFAULT 0,
  'promo_sellos' INT NOT NULL DEFAULT 0,
  'gratis_comprados' INT NOT NULL DEFAULT 0,
  'gratis_disponibles' INT NOT NULL DEFAULT 0,
  PRIMARY KEY ('id'),
  INDEX 'fk_cliente_idx' ('id_cliente' ASC),
  CONSTRAINT 'fk_cliente'
    FOREIGN KEY ('id_cliente')
    REFERENCES 'pasteleria'.'Clientes' ('id')
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

And these classes defined with netbeans and the hibernate wizard

public class Perfiles implements java.io.Serializable {

    //se autogenera al guardarlo
    private Integer id;
    private String perfil;
    private String descripcion;
    private Set<Usuarios> usuarioses = new HashSet<Usuarios>(0);

    public Perfiles() {
    }

    public Perfiles(String perfil, String descripcion) {
        this.perfil = perfil;
        this.descripcion = descripcion;
    }

    public Perfiles(String perfil, String descripcion, Set<Usuarios> usuarioses) {
        this.perfil = perfil;
        this.descripcion = descripcion;
        this.usuarioses = usuarioses;
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getPerfil() {
        return this.perfil;
    }

    public void setPerfil(String perfil) {
        this.perfil = perfil;
    }

    public String getDescripcion() {
        return this.descripcion;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public Set<Usuarios> getUsuarioses() {
        return this.usuarioses;
    }

    public void setUsuarioses(Set<Usuarios> usuarioses) {
        this.usuarioses = usuarioses;
    }

}
public class Usuarios  implements java.io.Serializable {


     private Integer id;
     private Perfiles perfiles;
     private String nick;
     private String pass;
     private Set<Clientes> clienteses = new HashSet<Clientes>(0);

    public Usuarios() {
    }


    public Usuarios(Perfiles perfiles, String nick, String pass) {
        this.perfiles = perfiles;
        this.nick = nick;
        this.pass = pass;
    }
    public Usuarios(Perfiles perfiles, String nick, String pass, Set<Clientes> clienteses) {
       this.perfiles = perfiles;
       this.nick = nick;
       this.pass = pass;
       this.clienteses = clienteses;
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    public Perfiles getPerfiles() {
        return this.perfiles;
    }

    public void setPerfiles(Perfiles perfiles) {
        this.perfiles = perfiles;
    }
    public String getNick() {
        return this.nick;
    }

    public void setNick(String nick) {
        this.nick = nick;
    }
    public String getPass() {
        return this.pass;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }
    public Set<Clientes> getClienteses() {
        return this.clienteses;
    }

    public void setClienteses(Set<Clientes> clienteses) {
        this.clienteses = clienteses;
    }    

}

public class Clientes implements java.io.Serializable {

    //Cedula
    private String id;
    //id del usuario
    private Usuarios usuarios;
    private String nombre;
    private String apellido;
    private String nacionalidad;
    //en teoria deberia tener solo una pero hibernate hizo el mapeo
    private Set<Tcp> tcps = new HashSet<Tcp>(0);

    public String getNacionalidad() {
        return nacionalidad;
    }

    public void setNacionalidad(String nacionalidad) {
        this.nacionalidad = nacionalidad;
    }

    public Clientes() {
    }

    public Clientes(String id, Usuarios usuarios, String nombre, String apellido) {
        this.id = id;
        this.usuarios = usuarios;
        this.nombre = nombre;
        this.apellido = apellido;
    }

    public Clientes(String id, Usuarios usuarios, String nombre, String apellido, Set<Tcp> tcps) {
        this.id = id;
        this.usuarios = usuarios;
        this.nombre = nombre;
        this.apellido = apellido;
        this.tcps = tcps;
    }

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Usuarios getUsuarios() {
        return this.usuarios;
    }

    public void setUsuarios(Usuarios usuarios) {
        this.usuarios = usuarios;
    }

    public String getNombre() {
        return this.nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getApellido() {
        return this.apellido;
    }

    public void setApellido(String apellido) {
        this.apellido = apellido;
    }

    public Set<Tcp> getTcps() {
        return this.tcps;
    }

    public void setTcps(Set<Tcp> tcps) {
        this.tcps = tcps;

}}

public class Tcp  implements java.io.Serializable {


     private Integer id;
     private Clientes clientes;
     private int totalSellos;
     private int promoSellos;
     private int gratisComprados;
     private int gratisDisponibles;
     private Set<Facturas> facturases = new HashSet<Facturas>(0);

    public Tcp() {
    }


    public Tcp(Clientes clientes, int totalSellos, int promoSellos, int gratisComprados, int gratisDisponibles) {
        this.clientes = clientes;
        this.totalSellos = totalSellos;
        this.promoSellos = promoSellos;
        this.gratisComprados = gratisComprados;
        this.gratisDisponibles = gratisDisponibles;
    }
    public Tcp(Clientes clientes, int totalSellos, int promoSellos, int gratisComprados, int gratisDisponibles, Set<Facturas> facturases) {
       this.clientes = clientes;
       this.totalSellos = totalSellos;
       this.promoSellos = promoSellos;
       this.gratisComprados = gratisComprados;
       this.gratisDisponibles = gratisDisponibles;
       this.facturases = facturases;
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    public Clientes getClientes() {
        return this.clientes;
    }

    public void setClientes(Clientes clientes) {
        this.clientes = clientes;
    }
    public int getTotalSellos() {
        return this.totalSellos;
    }

    public void setTotalSellos(int totalSellos) {
        this.totalSellos = totalSellos;
    }
    public int getPromoSellos() {
        return this.promoSellos;
    }

    public void setPromoSellos(int promoSellos) {
        this.promoSellos = promoSellos;
    }
    public int getGratisComprados() {
        return this.gratisComprados;
    }

    public void setGratisComprados(int gratisComprados) {
        this.gratisComprados = gratisComprados;
    }
    public int getGratisDisponibles() {
        return this.gratisDisponibles;
    }

    public void setGratisDisponibles(int gratisDisponibles) {
        this.gratisDisponibles = gratisDisponibles;
    }
    public Set<Facturas> getFacturases() {
        return this.facturases;
    }

    public void setFacturases(Set<Facturas> facturases) {
        this.facturases = facturases;
    }

The problem I have is that I want to create a Tcp for the newly registered client, but I get the following error (it should be noted that when I register a client I have to create a user first, followed in the code I create the client but I have to pass that previously created user to assign it to the client and there it works but if the client passes to the method that the TCP creates (it is also executed often after creating the client correctly) it tells me that, as if there inserted the client record, although I check the base and if it is, if I execute the method from the unit test if I create the tcp - sending it as a parameter the client that was created from the page -):

24-Aug-2017 15:44:50.667 WARN [http-nio-8084-exec-10] org.hibernate.action.internal.UnresolvedEntityInsertActions.logCannotResolveNonNullableTransientDependencies HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.
    Unsaved transient entity: ([com.pasteleria.web.domain.Clientes#21341221123])
    Dependent entities: ([[com.pasteleria.web.domain.Tcp#<null>]])
    Non-nullable association(s): ([com.pasteleria.web.domain.Tcp.clientes])
org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : com.pasteleria.web.domain.Tcp.clientes -> com.pasteleria.web.domain.Clientes
    at org.hibernate.action.internal.UnresolvedEntityInsertActions.checkNoUnresolvedActionsAfterOperation(UnresolvedEntityInsertActions.java:137)
    at org.hibernate.engine.spi.ActionQueue.checkNoUnresolvedActionsAfterOperation(ActionQueue.java:314)
    at org.hibernate.internal.SessionImpl.checkNoUnresolvedActionsAfterOperation(SessionImpl.java:654)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:713)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:703)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:698)
    at com.pasteleria.web.dao.TcpDAO.crearTcpCliente(TcpDAO.java:82)
    at com.pasteleria.web.controlador.nuevaTcpCliente.processRequest(nuevaTcpCliente.java:43)
    at com.pasteleria.web.controlador.nuevaTcpCliente.doGet(nuevaTcpCliente.java:62)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

This is the method that executes the registration

protected void processRequest(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException, IllegalStateException, SystemException {
        res.setContentType("text/html;charset=UTF-8");
        //primero comprobar los campos del formulario



        //el perfil del usuario registrado es de tipo cliente
        //se seleciona un perfil ya creado para asignarselo al nuevo cliente
        PerfilesDAO perfilesDAO = new PerfilesDAO();
        Perfiles perfilCliente = perfilesDAO.perfilPorID(2);

        UsuarioDAO usuariosDAO = new UsuarioDAO();
        Usuarios nuevoUsuario = new Usuarios();
        nuevoUsuario.setNick(req.getParameter("nick"));
        nuevoUsuario.setPass(req.getParameter("pass1"));
        nuevoUsuario.setPerfiles(perfilCliente);
        usuarioDAO.nuevoUsuario(nuevoUsuario);


        // definir el cliente antes de registrarlo
        Clientes nuevoCliente = new Clientes();
        nuevoCliente.setNombre(req.getParameter("nombre"));
        nuevoCliente.setId(req.getParameter("cedula"));
        nuevoCliente.setApellido(req.getParameter("apellido"));
        nuevoCliente.setNacionalidad(req.getParameter("nacionalidad"));
        nuevoCliente.setUsuarios(nuevoUsuario);

        //registrar el cliente definido anteriormente
        int resCliente = clientesDAO.nuevoCliente(nuevoCliente);

        if (resCliente == 1) {
            //el cliente se creo correctamente y se debe de redirigir al 

login
            // antes crear la tarjeta pastelera

            //este es para ver si el cliente se registro y lo obtenerlo de la base para ver 
            //si asi reconocia al cliente pero tampoco
            Clientes cliente = clientesDAO.getClienteByCed(nuevoCliente.getId());
            //si no lo encontrara me manda de nuevo al registro
            if (cliente == null) {
                req.setAttribute("err", -6);
                this.getServletContext().getRequestDispatcher("/registro.jsp").forward(req, res);
                return;
            }

            System.out.println("La nueva cedula es :" + nuevoCliente.getId());
            //capa para crear el TCP
            TcpDAO tcpDAO = new TcpDAO();
            int i = tcpDAO.crearTcp(cliente);
            System.out.println("crearTcp>>   " + i + "    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            if (i == 1) {
            req.getSession().setAttribute("ced", nuevoCliente.getId());
            //this.getServletContext().getRequestDispatcher("/nuevatcpcliente").forward(req, res);
            res.sendRedirect("login.jsp");
            } else {
                req.setAttribute("err", -5);
                this.getServletContext().getRequestDispatcher("/registro.jsp").forward(req, res);
            }

        } else {
            //borrar usuario por que el cliente no pudo crear
            usuarioDAO.eliminarUsuario(nuevoUsuario);
            req.setAttribute("err", -4);
            this.getServletContext().getRequestDispatcher("/registro.jsp").forward(req, res);
        }

        //else{
//            this.getServletContext().getRequestDispatcher("/registro.jsp").forward(req, res);
//        }
    }

Used methods of DAO classes ProfilesDAO

public class PerfilesDAO(){
    public Perfiles perfilPorID(int id) {
        SessionFactory sesionF = HibernateUtil.getSessionFactory();
        Session sesion = sesionF.openSession();
        Perfiles perfil = null;
        try {
            Query q = sesion.createQuery("from Perfiles where id ='" + id + "'");
            perfil = (Perfiles) q.uniqueResult();
            if (perfil != null) {
                return perfil;
            } else {
                return perfil;
            }
        } catch (Exception e) {
            return perfil;
        } finally {
            sesion.close();
        }
    }
}

UserDAO     public class UsuarioDAO {

    public int nuevoUsuario(Usuarios usuario) {
        SessionFactory sesionF = HibernateUtil.getSessionFactory();
        Session sesion = sesionF.openSession();
        Transaction tx = (Transaction) sesion.beginTransaction();
        try {
            int res = getUsuarioInt(usuario.getNick(), usuario.getPass());
            switch (res) {
                //el nick ingresado no se encontró en el sistema
                case -1:
                    boolean isPerfil = PerfilesDAO.isPerfilPorID(usuario.getPerfiles().getId());
                    if (isPerfil) {
                        sesion.save(usuario);
                        tx.commit();
                        return 0;
                    } else {
                        return -3;
                    }
                case 0:
                    return -1;
                default:
                    return -2;
            }
        } catch (IllegalStateException | SystemException e) {
            System.out.println("Error en nuevo usuario: " + e.getMessage());
            tx.rollback();
        } finally {
            sesion.close();
        }
        return -2;
    }
}

ClienteDAO

public class ClienteDAO {

    public int nuevoCliente(Clientes cliente) throws IllegalStateException, SystemException {
        Session sesion = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = sesion.beginTransaction();
        //comprobar que exista el usuario que tiene el cliente en el parametro
        UsuarioDAO usuarioDAO = new UsuarioDAO();
        //comprobar que antes se creara el usuario en el sistema luego se asigna los datos personales de ese 
        //cliente
        try {
            int iUsuario = usuarioDAO.getUsuarioInt(cliente.getUsuarios().getNick(), cliente.getUsuarios().getPass());
            if (iUsuario == 1) {
                sesion.saveOrUpdate(cliente);
                tx.commit();
                return 1;
            }
        } catch (Exception e) {
            tx.rollback();
            e.printStackTrace();
        } finally {
            sesion.close();
        }
        return 0;
    }

    public boolean isCliente(String ced) {
        Session sesion = HibernateUtil.getSessionFactory().openSession();
        try {
            Query q = sesion.createQuery("from Clientes where id='" + ced + "'");
            if (q.uniqueResult() != null) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sesion.close();
        }
        return false;
    }
}

TcpDAO
Here also valid that the client exists

public class ClienteDAO();
public int crearTcp(Clientes cliente) {
        Session sesion = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = sesion.beginTransaction();
        Query q;
        ClienteDAO clienteDAO = new ClienteDAO();
        if (cliente == null) {
            return -4;
        }
        try {
            boolean iC = clienteDAO.isCliente(cliente.getId());
            if (!iC) {
                return -3;
            }
            q = sesion.createQuery("from Tcp where id_cliente ='" + cliente.getId() + "'");
            Tcp tcp = (Tcp) q.uniqueResult();
            if (tcp == null) {
                tcp = new Tcp();
                tcp.setClientes(cliente);
                sesion.save(tcp);
                tx.commit();
                return 1;
            } else {
                return -1;
            }
        } catch (Exception e) {
            System.out.println("Error+" + e.getMessage());
            e.printStackTrace();
        } finally {
            sesion.close();
        }
        return -2;
    }
}

Pox's xml files Clients.hbm.xml

<hibernate-mapping>
    <class name="com.pasteleria.web.domain.Clientes" table="clientes" catalog="pasteleria" optimistic-lock="version">
        <id name="id" type="string">
            <column name="id" length="11" />
            <generator class="assigned" />
        </id>
        <many-to-one name="usuarios" class="com.pasteleria.web.domain.Usuarios" fetch="select">
            <column name="id_usu" not-null="true" />
        </many-to-one>
        <property name="nombre" type="string">
            <column name="nombre" length="45" not-null="true" />
        </property>
        <property name="apellido" type="string">
            <column name="apellido" length="45" not-null="true" />
        </property>
        <property name="nacionalidad" type="string">
            <column name="nacionalidad" length="100" not-null="true" />
        </property>
        <set name="tcps" table="tcp" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="id_cliente" length="11" not-null="true" />
            </key>
            <one-to-many class="com.pasteleria.web.domain.Tcp" />
        </set>
    </class>
</hibernate-mapping>

Tcp.hbm.xml

<hibernate-mapping>
    <class name="com.pasteleria.web.domain.Tcp" table="tcp" catalog="pasteleria" optimistic-lock="version">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <many-to-one name="clientes" class="com.pasteleria.web.domain.Clientes" fetch="select">
            <column name="id_cliente" length="11" not-null="true" />
        </many-to-one>
        <property name="totalSellos" type="int">
            <column name="total_sellos" not-null="true" />
        </property>
        <property name="promoSellos" type="int">
            <column name="promo_sellos" not-null="true" />
        </property>
        <property name="gratisComprados" type="int">
            <column name="gratis_comprados" not-null="true" />
        </property>
        <property name="gratisDisponibles" type="int">
            <column name="gratis_disponibles" not-null="true" />
        </property>
        <set name="facturases" table="facturas" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="id_tcp" not-null="true" />
            </key>
            <one-to-many class="com.pasteleria.web.domain.Facturas" />
        </set>
    </class>
</hibernate-mapping>
    
asked by 25.08.2017 в 00:18
source

0 answers