004 - Aplicación de Stock con Java. Hibernate – MySQL – JPA. Creando clases persistentes.

En la siguiente imagen pueden ver el modelo de datos que utilizaremos para nuestra aplicación. Este modelo los traduciremos en clases persistentes que utilizaremos para manejar todo tipo de transacciones. (Mod. 1)
Modelo DER Base de Datos
Empezamos por lo fácil, creando la clase persistente “Tipo”. Este representa la tabla “tipo” del modelo de datos, cada registro de esta representa un grupo de artículos filtrados por; como su nombre índica “tipo” de artículos. La relación entre “Tipo” y “Articulo” es de “Uno a Muchos bidireccional”. Con esto podemos navegar de ambas tabla viendo esto desde la perspectiva de MySQL, ej., podemos obtener un registro “Tipo” y a través de esta utilizando listas de todos los “Articulos” relacionadas a la misma. Las clases las crearemos de a uno, por tanto mientras no estén todas Java indicaré ciertos errores, esto por la relación que hay entre las clases persistentes. Empecemos.
Pasos previos. Estas serán iguales para crea cada una de las clases persistentes.
Debemos hacer clic derecho sobre el paquete “com.entidades” que hemos creado con anterioridad, clic en “Nuevo” y en “Clase Java…” (Img. 01).
Creando Clases
En la pantalla siguiente indicamos el “Nombre de Clase”; si creamos la clase como se indica, en “Paquete” no mostrará el nombre “com.entidades”. Por último clic en “Terminar” (Img. 02).
Creando Clases
Esta nos crea una plantilla con el paquete a la que pertenece la clase y nombre de esta. (Img. 03) Esta plantilla es la que modificaremos para que funcione como clase persistente.
Plantilla de Clase
Clase persistente “Tipo.java”.

Código Java
package com.entidades;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

/**
 *
 * @author ariel
 */
@Entity
public class Tipo implements Serializable {
    private List<Articulo> articulos = new ArrayList<Articulo>();
    private int id;
    private String des;
    
    @Column(length=50)
    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }
    
    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    public int getId() {
        return id;
    }

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

    @OneToMany(mappedBy = "tipo",cascade= CascadeType.ALL)
    public List<Articulo> getArticulos() {
        return articulos;
    }

    public void setArticulos(List<Articulo> articulos) {
        this.articulos = articulos;
    }
    
}



Explicación de algunos detalles.
Imports
Imagen(04)

  • (1) Nos indica el paquete a la que pertenece la clase.
  • (2) Muestra la lista de importaciones que requiere la clase para que funcione.
    Clase Tipo
    Imagen(05)
    Antes que nada debemos saber que cada variable privada de la clase debe tener un par de “Setters y Getters” para tener acceso a ellas. Todas las anotaciones JPA se realizan sobre las líneas de los “Getters”.
  • (1) “@Entity” es una anotación con JPA, la cual indica que la clase representa una entidad.
  • (2) Toda clase que sea persistente debe implementar la interfaz “Serializable”. Es lo que indicamos en esta línea.
  • (3) En esta línea indicamos una variables de tipo “List”, ya que la clase “Tipo” como tiene relación con la clase “Articulo” (que la crearemos) de “Uno-a-Mucho” bidireccional debe crea una variable de tipo “java.util.List” lo cual nos indica que una clase “Tipo” puede relacionarse con una lista de clases “Articulo”.
  • (4) “@Column(length=50)” con esta anotación indicamos que la columna “des” que esta debajo posee una extensión de 50 caracteres.
  • (5) “@Id” anotación que indica que la columna, en este caso “id” es la que será la llave primaria dentro de la tabla.
  • (6) “@GeneratedValue(strategy= GenerationType.IDENTITY)” estamos indicando con esta anotación que el “Id” se va ha generar de forma automática o mejor dicho de tipo autoincremental. Con esto no tendremos que preocuparnos del valor que pueda tomar la llave primaria. Es importante ya que los valores se generan de forma secuencial por tanto no hay posibilidad que se repitan. Como sabemos las llaves primarias deben ser únicas.
  • (7) “@OneToMany(mappedBy = "tipo",cascade= CascadeType.ALL)” en esta línea estamos indicando expresamente el tipo de relación que va tener la clase “Tipo” con la clase “Artículo” y que variable del otro lado (Articulo) va representar a la clase “Tipo” (mappedBy = "tipo"). También indicamos el tipo de actualización de la relación con la línea (cascade= CascadeType.ALL), esto quiere decir que si eliminamos un registro del lado de “Tipo” también se eliminan todos los registro del lado de “Artículo” que estén relacionado con esta. Es importante para no dejar registros huérfanos o similares.


    Clase persistente “Articulo.java”.


  • Código Java
    package com.entidades;
    
    import java.io.Serializable;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.ManyToOne;
    
    /**
     *
     * @author Toshiba
     */
    @Entity
    public class Articulo implements Serializable {
        private int id;
        private String des;
        private int pco;
        private int por;
        private int pve;
        private int can;
        private Tipo tipo;
    
        public int getCan() {
            return can;
        }
    
        public void setCan(int can) {
            this.can = can;
        }
    
        public String getDes() {
            return des;
        }
    
        public void setDes(String des) {
            this.des = des;
        }
        
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY)
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getPco() {
            return pco;
        }
    
        public void setPco(int pco) {
            this.pco = pco;
        }
    
        public int getPor() {
            return por;
        }
    
        public void setPor(int por) {
            this.por = por;
        }
    
        public int getPve() {
            return pve;
        }
    
        public void setPve(int pve) {
            this.pve = pve;
        }
    
        @ManyToOne
        public Tipo getTipo() {
            return tipo;
        }
    
        public void setTipo(Tipo tipo) {
            this.tipo = tipo;
        }
        
           
        
    }
    


    Explicación de algunos detalles.
    Solo explicaremos algunas de las anotaciones que sean diferentes a las anotaciones de la anterior “Clase” que ya hemos explicado o que puedan ser de interés especial.
    Clase Articulo
    Imagen(06)

  • (1) Declaramos una variable privada de “Tipo” con nombre “tipo” la cual representa a la clase “Tipo” con la cual esta clase “Articulo” posee una relación. Como del lado de “Articulo” varios registros pueden relacionarse con un solo registro “Tipo” esta no se representa como una lista, como se hizo en la clase anterior.
    Clase Articulo
    Imagen(07)
  • (1) “@ManyToOne” con esta anotación indicamos que del lado la Clase “Articulo” serán muchos registros relacionados con una del lado de la Clase “Tipo”. Como vemos no se ha indicado la anotación ((mappedBy = "tipo",cascade= CascadeType.ALL) que teníamos en la clase “Tipo”. Esto es porque siempre del lado del (OneToMany) se toma el control de la relación, quedando el (ManyToOne) como dependiente.

    Clase persistente “Cliente.java”.
    Código Java
    package com.entidades;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    
    /**
     *
     * @author Ariel
     */
    @Entity
    public class Cliente implements Serializable {
        private List<VentaCab> ventaCabs = new ArrayList<VentaCab>();
        private int id;
        private String des;
        private String dir;
        private String tel;
        private String ruc;
    
        public String getDes() {
            return des;
        }
    
        public void setDes(String des) {
            this.des = des;
        }
    
        public String getDir() {
            return dir;
        }
    
        public void setDir(String dir) {
            this.dir = dir;
        }
        
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY)
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getRuc() {
            return ruc;
        }
    
        public void setRuc(String ruc) {
            this.ruc = ruc;
        }
    
        public String getTel() {
            return tel;
        }
    
        public void setTel(String tel) {
            this.tel = tel;
        }
    
        @OneToMany(mappedBy = "cliente")
        public List<VentaCab> getVentaCabs() {
            return ventaCabs;
        }
    
        public void setVentaCabs(List<VentaCab> ventaCabs) {
            this.ventaCabs = ventaCabs;
        }
        
    }
    

    Como podemos ver esta clase posee una única relación de tipo (OneToMany), que ya se ha explicado con anterioridad. La diferencia sería que no posee la anotación (cascade= CascadeType.ALL) ya que la relación es con la Clase que representa “Venta”, cuyos registro no deberían eliminarse.


    Clase persistente “Funcionario.java”.


  • Código Java
    package com.entidades;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    
    /**
     *
     * @author Ariel
     */
    @Entity
    public class Funcionario implements Serializable {
        private List<CompraCab> compraCabs = new ArrayList<CompraCab>();
        private List<VentaCab> ventaCabs = new ArrayList<VentaCab>();
        private int id;
        private String nombres;
        private String apellidos;
        private String dir;
        private String tel;
        private String cargo;
    
        public String getApellidos() {
            return apellidos;
        }
    
        public void setApellidos(String apellidos) {
            this.apellidos = apellidos;
        }
    
        public String getCargo() {
            return cargo;
        }
    
        public void setCargo(String cargo) {
            this.cargo = cargo;
        }
    
        public String getDir() {
            return dir;
        }
    
        public void setDir(String dir) {
            this.dir = dir;
        }
        
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY)
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getNombres() {
            return nombres;
        }
    
        public void setNombres(String nombres) {
            this.nombres = nombres;
        }
    
        public String getTel() {
            return tel;
        }
    
        public void setTel(String tel) {
            this.tel = tel;
        }
    
        @OneToMany(mappedBy = "funcionario")
        public List<VentaCab> getVentaCabs() {
            return ventaCabs;
        }
    
        public void setVentaCabs(List<VentaCab> ventaCabs) {
            this.ventaCabs = ventaCabs;
        }
    
        @OneToMany(mappedBy = "funcionario")
        public List<CompraCab> getCompraCabs() {
            return compraCabs;
        }
    
        public void setCompraCabs(List<CompraCab> compraCabs) {
            this.compraCabs = compraCabs;
        }
        
        
    }
    


    Esta clase a diferencia de “Cliente” posee relación de tipo (OneToMany), con dos Clases que son las que representan “Compra” y “Venta”.


    Clase persistente “Proveedor.java”.

    Código Java
    package com.entidades;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    
    /**
     *
     * @author Ariel
     */
    @Entity
    public class Proveedor implements Serializable {
        private List<CompraCab> compraCabs = new ArrayList<CompraCab>();
        private int id;
        private String des;
        private String dir;
        private String tel;
    
        public String getDes() {
            return des;
        }
    
        public void setDes(String des) {
            this.des = des;
        }
    
        public String getDir() {
            return dir;
        }
    
        public void setDir(String dir) {
            this.dir = dir;
        }
        
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY)
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getTel() {
            return tel;
        }
    
        public void setTel(String tel) {
            this.tel = tel;
        }
    
        @OneToMany(mappedBy = "proveedor")
        public List<CompraCab> getCompraCabs() {
            return compraCabs;
        }
    
        public void setCompraCabs(List<CompraCab> compraCabs) {
            this.compraCabs = compraCabs;
        }
        
    }
    


    Esta clase posee una relación de tipo (OneToMany) con la Clase que representa “Compra”. Tipo de relación que ya explicamos.


    Clase persistente “VentaCab.java”.

    Código Java
    package com.entidades;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.List;
    import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.ManyToOne;
    import javax.persistence.OneToMany;
    import javax.persistence.Temporal;
    
    /**
     *
     * @author Ariel
     */
    @Entity
    public class VentaCab implements Serializable {
        private List<VentaDet> ventaDets = new ArrayList<VentaDet>();
        private int num;
        private Cliente cliente;
        private Funcionario funcionario;
        private Calendar fecha;
        private String hora;
        private long total;
    
        public long getTotal() {
            return total;
        }
    
        public void setTotal(long total) {
            this.total = total;
        }    
        
        @ManyToOne
        public Cliente getCliente() {
            return cliente;
        }
    
        public void setCliente(Cliente cliente) {
            this.cliente = cliente;
        }
    
        @Temporal(javax.persistence.TemporalType.DATE)
        public Calendar getFecha() {
            return fecha;
        }
    
        public void setFecha(Calendar fecha) {
            this.fecha = fecha;
        }
    
        @ManyToOne
        public Funcionario getFuncionario() {
            return funcionario;
        }
    
        public void setFuncionario(Funcionario funcionario) {
            this.funcionario = funcionario;
        }
    
        public String getHora() {
            return hora;
        }
    
        public void setHora(String hora) {
            this.hora = hora;
        }
        
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY)
        public int getNum() {
            return num;
        }
    
        public void setNum(int num) {
            this.num = num;
        }
    
        @OneToMany(mappedBy = "ventaCab",cascade= CascadeType.ALL)
        public List<VentaDet> getVentaDets() {
            return ventaDets;
        }
    
        public void setVentaDets(List<VentaDet> ventaDets) {
            this.ventaDets = ventaDets;
        }
        
        
    }
    


    Explicación de algunos detalles.
    Clase que representa la cabecera de la Clase “Venta”. Como sabemos una transacción normalmente posee una tabla de tipo cabecera y otra de tipo detalle. En este caso la diferencia es que estas son clases y nada más. Algo importante de mencionar es la línea que incluye el objeto tipo Calendar que declaramos (private Calendar fecha;). La anotación para Calendar si utilizamos de ella fecha es como se indica (@Temporal(javax.persistence.TemporalType.DATE)). Si no indicamos como esta, podría dar pie a errores.
    Clase VentaCab
    Imagen(08)

  • (1) “private List ventaDets = new ArrayList();” estamos indicando una relación a través de una variable de tipo “List” con una Clase que se llama “VentaDet”. Esta relación es de tipo (OneToMany), con lo cual queremos decir que una venta cabecera puede contener varios detalles; las cuales almacenaremos en una lista.
  • (2) Indicamos que hay una relación con la clase “Cliente”. Dicho de otra forma, cada venta se debe realizar a un cliente y nada más.
  • (3) Indicamos que hay una relación con la clase “Funcionario”. Lo que vemos es que un funcionario debe ser responsable de realizar la venta.

    Clase persistente “VentaDet.java”.


  • Código Java
    package com.entidades;
    
    import java.io.Serializable;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.ManyToOne;
    
    /**
     *
     * @author Ariel
     */
    @Entity
    public class VentaDet implements Serializable {
        private int num;
        private Articulo articulo;
        private int cant;
        private int importe;
        private VentaCab ventaCab;
    
        @ManyToOne
        public Articulo getArticulo() {
            return articulo;
        }
    
        public void setArticulo(Articulo articulo) {
            this.articulo = articulo;
        }
    
        public int getImporte() {
            return importe;
        }
    
        public void setImporte(int importe) {
            this.importe = importe;
        }
        
        public int getCant() {
            return cant;
        }
    
        public void setCant(int cant) {
            this.cant = cant;
        }
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY)
        public int getNum() {
            return num;
        }
        
        public void setNum(int num) {
            this.num = num;
        }
    
        @ManyToOne
        public VentaCab getVentaCab() {
            return ventaCab;
        }
    
        public void setVentaCab(VentaCab ventaCab) {
            this.ventaCab = ventaCab;
        }   
        
    }
    


    Explicación de algunos detalles.
    En la Clase “VentaDet” vemos que hay una relación de tipo (ManyToOne) unidireccional con la clase “Articulo”. Con esto indicamos que un artículo puede relacionarse como muchas clases “VentaDet”, pero que no hace falta indicar una relación desde la Clase “Articulo”. También vemos que hay una relación de tipo (ManyToOne) bidireccional con la Clase “VentaCab”. Como indicamos más arriba una clase “VentaCab” puede contener varias Clases de tipo “VentaDet” y esta última puede relacionarse con una sola Clase “VentaCab”. Como vemos hay una relación de dependencia.


    Clase persistente “CompraCab.java”.

    Código Java
    package com.entidades;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.List;
    import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.ManyToOne;
    import javax.persistence.OneToMany;
    import javax.persistence.Temporal;
    
    /**
     *
     * @author Ariel
     */
    @Entity
    public class CompraCab implements Serializable {
        private List<CompraDet> compraDets = new ArrayList<CompraDet>();
        private int id;
        private int num;
        private Proveedor proveedor;
        private Funcionario funcionario;
        private Calendar fecha;
        private String hora;
        private long total;
    
        public int getNum() {
            return num;
        }
    
        public void setNum(int num) {
            this.num = num;
        }
            
        @Temporal(javax.persistence.TemporalType.DATE)
        public Calendar getFecha() {
            return fecha;
        }
    
        public void setFecha(Calendar fecha) {
            this.fecha = fecha;
        }
    
        
        @ManyToOne
        public Funcionario getFuncionario() {
            return funcionario;
        }
    
        public void setFuncionario(Funcionario funcionario) {
            this.funcionario = funcionario;
        }
    
        public String getHora() {
            return hora;
        }
    
        public void setHora(String hora) {
            this.hora = hora;
        }
        
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY)
        public int getId() {
            return id;
        }
        
        
        public void setId(int id) {
            this.id = id;
        }
    
       
        @ManyToOne
        public Proveedor getProveedor() {
            return proveedor;
        }
    
        public void setProveedor(Proveedor proveedor) {
            this.proveedor = proveedor;
        }
    
        public long getTotal() {
            return total;
        }
    
        public void setTotal(long total) {
            this.total = total;
        }
    
        @OneToMany(mappedBy = "cabecera",cascade= CascadeType.ALL)
        public List<CompraDet> getCompraDets() {
            return compraDets;
        }
    
        public void setCompraDets(List<CompraDet> compraDets) {
            this.compraDets = compraDets;
        }
            
    }
    


    Explicación de algunos detalles.
    Al igual que “VentaCab” la clase “CompraCab” representa la cabecera que corresponde a la transacción “Venta”. La Clase como se ve se relaciona con las Clases “Funcionario” (ManyToOne), “Proveedor” también (ManyToOne) y con “VentaDet” que es de tipo (OneToMany). Al igual que en “VentaCab” para la fecha se utiliza el objeto Calendar.


    Clase persistente “CompraDet.java”.

    Código Java
    package com.entidades;
    
    import java.io.Serializable;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.ManyToOne;
    
    /**
     *
     * @author Ariel
     */
    @Entity
    public class CompraDet implements Serializable {
        private int id;
        private CompraCab cabecera;
        private Articulo articulo;
        private int cantidad;
        private long importe;
    
        @ManyToOne
        public Articulo getArticulo() {
            return articulo;
        }
    
        public void setArticulo(Articulo articulo) {
            this.articulo = articulo;
        }
    
        @ManyToOne
        public CompraCab getCabecera() {
            return cabecera;
        }
    
        public void setCabecera(CompraCab cabecera) {
            this.cabecera = cabecera;
        }
    
        public int getCantidad() {
            return cantidad;
        }
    
        public void setCantidad(int cantidad) {
            this.cantidad = cantidad;
        }
        
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY)
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public long getImporte() {
            return importe;
        }
    
        public void setImporte(long importe) {
            this.importe = importe;
        }   
        
        
    }
    


    Explicación de algunos detalles.
    La estructura de esta clase es prácticamente igual que la de “VentaDet”, la diferencia es que “CompraDet” tiene que realizar una actualización positiva del stock, dicho de otra forma, se suman las cantidades a diferencia de la anterior.
    Con esto último terminamos la creación de las clases persistentes. Lo siguiente será empezar a crear formularios y almacenar datos.

    Al terminar de elaborar nuestras clases persistentes, tendremos que modificar el “hibernate.cfg” desde “Vista XML”, agregando las clases persistentes que hemos creado. El “hibernate.cfg” deberá quedar de la siguiente forma. Imagen(09).


    Imagen(09)

    9 comentarios :

    1. seguimos con esto .. gracias por el articulo !

      ResponderEliminar
    2. Muy bueno Carlos, ya llegue hasta esta parte y me gusta mucho como lo explicas. Te Felicito

      ResponderEliminar
    3. Realmente impecable. He visto muchos tutoriales, pero lo suyo es majestuoso.
      Lo felicito y le agradezco

      ResponderEliminar
      Respuestas
      1. Gracias por el comentario amigo, espero que el material te haya sido de utilidad. Saludos.

        Eliminar
    4. Este comentario ha sido eliminado por el autor.

      ResponderEliminar
      Respuestas
      1. Que tal Abigail. Solo son palabras recortadas, son campos de la tabla “Articulo”, por ejemplo “des” para “descripción”, “pco” –precio de compra, “por” –porcentaje de ganancia, “pve” –precio de venta, “can”-cantidad. El “ruc” es el registro único que se usa en nuestro país, se usa en la tabla “Cliente”. Cuando hay transacciones se suelen usar dos “Tablas” para representarlas, en este caso, “copracab” –Compra cabecear y “compradet” –Compra detalle. Es igual para “Ventas”. Es la forma habitual de nombrar campos para facilitar la escritura de código. Disculpa que no haya especificado estos detalles. Gracias por el comentario.

        Eliminar
      2. Este comentario ha sido eliminado por el autor.

        Eliminar
    5. Me encanta, muy bien explicado :) Bendiciones

      ResponderEliminar