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>