006 - Aplicación de Stock con Java. Hibernate – MySQL – JPA. Formulario referencial TipoApp.

Para crea un formulario que no sea principal recurriremos al “JDialog”, que es un tipo de formulario dependiente a diferencia del “JFrame”. Para ello hacemos clic derecho sobre el paquete en donde almacenaremos los formularios, en este caso “com.app”, clic en “Otros” y rellenamos los datos y selección como se indica en la imagen (JDialog 1). En la siguiente pantalla, le damos un nombre en este caso “TipoApp” para diferenciar de la clase persistente “Tipo”. Clic en “Terminar” y empezamos a diseñar.


(JDialog 1)
Seguimos viendo el diseño del formulario y los componentes que incluyen.(img. 1)

(Img. 1)
Componentes.
  • (1) JLabel que utilizamos para indicar con letras grandes y junto con un icono (se puede incluir iconos junto con el texto) una descripción del formulario.
  • (2) JPanel para agrupar los JLabels y JTextFields importantes para el usuario.
  • (3) JTextField para mostrar el id de la Clase Persistente “Tipo”, que ya se ha creado anteriormente. El usuario no requiere indicar un “id” ya que esta al crear la Clase “Tipo” le indicamos al Hibernate que es auto-numérico.
  • (4) JTextField para que el usuario indique una descripción para el tipo de articulo nuevo de desea crear. También según el caso el usuario podrá editar los datos de registros ya almacenados.
  • (5) JTable que nos permitirá visualizar los datos ya almacenados indicando por columnas “Código” y “Descripción”. “Código” corresponde al “Id” que en esencia son lo mismo. También la tabla permite seleccionar registros específicos para poder editarlos como veremos.
  • (6) JButtons que serían los botones de comando, las cuales como se ve en la imagen cumplen; cada una, un rol específico. Estos botones están dentro de un JPanel, ya que esta permite manejarlas como un grupo.
  • (7) “Fuente” y “Diseño”, las dos pestañas que nos permiten alternar entre “Vista de Diseño” y “Vista de Fuente”. En “Vista de Fuente” iremos agregando los métodos y funciones que utilizaremos.

    Lo siguiente es ver la distribución y nombre de cada uno de los componentes dentro del diseño. (img. 2)


    (Img. 2)
    Componentes.
  • (1) JDialog que sería como el objeto padre que almacena todas las demás y sobre la que diseñamos.
  • (2) JPanel la cual incluye todos los paneles y componentes que se agregan al formulario. Esto permite mover o copiar grupo de objetos de forma fácil.
  • (3) JPanel que agrupa los JLabels y JTextFields.
  • (4) jScrollPane para utilizar Scroll en la tabla, es automática. Al agregar la tabla se suele agregar también.
  • (5) JPanel que nos permite agrupar los botones de comando del formulario.
  • (6) JButtons dentro del JPanel.

    Cambiar nombre de variables y textos visibles de objetos. (img. 3)


    (Img. 3)

    El menú se despliega haciendo clic derecho sobre el objeto específico.

  • (1) Editar Texto esto nos permite cambiar el texto visible, como se ve en la imagen el nombre para cada JButton.
  • (2) Cambiar nombre de variable… esta opción nos permite cambiar el nombre de variable de un objeto, la cual es la que utilizamos para llamarla desde cualquier método o función que creemos. Por tanto es importante elegir un nombre de variable que sea definitorio de la función del objeto. (img. 4)

    (Img. 4)

    Como se ve en la imagen, se indican los nombres de variable que utilizaremos para los objetos con las que estaremos trabajando desde los métodos que crearemos. Esto es importante para hacer los códigos más legibles.

    Llamar métodos desde objetos específicos.

    Para ello hacemos clic derecho sobre el objeto específico (JButton, JTextFields, etc), seleccionamos “Eventos”, y del menú desplegado la que estemos necesitando. Cada evento funciona de una manera específica. Solo explicaremos las que vayamos utilizando dentro del proyecto. (img. 5)


    (Img. 5)

    Al seleccionar un “Evento”, NetBeans nos crea un método relacionado al objeto y evento específico; dentro de la cual agregaremos nuestro código o llamaremos métodos para que se ejecuten. (img. 6)


    (Img. 6)

    También podremos ver los “Eventos” relacionado a un objeto específico, haciendo clic derecho sobre el objeto y en “Propiedades” y pestaña “Eventos”. Desde este lugar podremos eliminar también los eventos que hayamos creado, seleccionado y “Suprimir”. Desde “Vista de Fuentes” no se pueden eliminar “Eventos”. (img. 7)


    (Img. 7)

    Importaciones necesarias.

    La lista.
    Código Java
    import com.entidades.Tipo;
    import java.util.Iterator;
    import java.util.List;
    import javax.swing.JOptionPane;
    import javax.swing.table.DefaultTableModel;
    import net.sf.jasperreports.engine.JasperFillManager;
    import net.sf.jasperreports.engine.JasperPrint;
    import net.sf.jasperreports.engine.JasperReport;
    import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
    import net.sf.jasperreports.engine.util.JRLoader;
    import net.sf.jasperreports.view.JasperViewer;
    import org.hibernate.Session;
    import util.HibernateUtil;


    Esquema del código fuente a tomar en cuenta. (img. 8).


    (Img. 8)

    Los método que se muestran, las iremos creando, esto es para ver su desde que lugar de Código Fuente tendremos que llamarlos.

  • (1) Lista de importaciones necesaria, se ubican en la zona de forma automática. Normalmente debe ir debajo del package.
  • (2) (sessionHibernate();) Un método que llamamos dentro del “Método Constructor” del JDialog para que se ejecute al crearse el objeto “JDialog”. Este método no permite crear lo que llamamos el “SessionFactory()” del Hibernate.
  • (3) (arranque();) Al igual que la anterior se ejecuta al crease el objeto. Ya explicaremos su función.
  • (4) (setLocationRelativeTo(null);) Método llamado también en el “Constructor”. Es un método que permite ubicar el JDialog en la pantalla, al pasarle “null”, la deja centrado.
  • (5) (private Session st;) Creamos una variable de clase tipo “Session” que nos permitirá guardar nuestra sesión del Hibernate y utilizarla en cualquiera de los métodos que creemos.
  • (6) (private DefaultTableModel model;) Variable de clase tipo “DefaultTableModel”, que ya explicaremos su función.
  • (7) Zona en la que se ubican todos los “Eventos” que vayamos implementando.
  • (8) (nuevo();) Ejemplo de cómo llamamos un “Método” desde un “Evento”.

    La consideración importante es que cualquier método que queramos que se ejecute al crearse el formulario debemos de llamarlos desde el “Método Constructor”. Pero siempre después del método “initComponents();” por regla.

    Otras zonas de la “Vista de fuentes” importantes de mencionar. (img. 9)


    (Img. 9)
  • (1) Zona donde se declaran las variables de los objetos que creemos en el formulario. No se pueden modificar desde “Vista de Fuentes” solo desde “Vista de Diseño”.
  • (2) Zona en la que de preferencia personal suelo ubicar los métodos que creo. Según tengo entendido con que sea fuera del “Método Constructor” se considera método de clase. En un formulario nuevo, debemos desplazar la llave “}“ de cierre y empezar a escribir nuestro método que podremos utilizar en cualquier parte del código. Creando Método y utilizando Eventos.

    Método “sessionHibernate()”. (Recuerden que el nombre del método es relativo, con que sea un nombre definitorio, para diferenciar de otras.)


    Código Java
    public void sessionHibernate(){
    st = HibernateUtil.getSessionFactory().openSession();
    }

    Este método asigna a la variable “st” una “SessionFactory”, la cual utilizaremos para guardar, actualizar, recuperar y eliminar registros. Este método debemos llamar desde el “Método Constructor” del JDialog.

    Método “arranque()”.
    Código Java
    public void arranque(){
    this.id.setEnabled(false);
    this.id.setText(null);
    this.des.setEnabled(false);
    this.des.setText(null);
    this.guardar.setEnabled(false);
    this.editar.setEnabled(false);
    this.eliminar.setEnabled(false);
    this.informe.setEnabled(true);
    this.nuevo.setEnabled(true);
    this.guardar.setText("Guardar");
    this.jTable1.setEnabled(true);
    defaultTableModel();
    cargarTabla();
    }

    Este método nos permite establecer que objeto del “Formulario” estarán habilitadas para su uso y que valores tendrán por defecto. Este método se llama desde el “Método Constructor” y desde el “Botón Cancelar” utilizando el “Evento” “ActionPerformed” (img. 10). Un punto importante es que para los objetos JButton normalmente se utilizar el “Evento” “ActionPerformed”. Para nuestro proyecto se sigue este esquema para todos los “JButton”. Más arriba explicamos como llamar métodos desde objetos específicos. Este método también incluye los métodos “defaultTableModel()” y “cargarTabla()” que ya crearemos y explicaremos su función.


    (Img. 10)

    Método “defaultTableModel()”
    Código Java
    public void defaultTableModel(){
    this.jTable1.getColumnModel().getColumn(0).setPreferredWidth(20);
    this.jTable1.getColumnModel().getColumn(1).setPreferredWidth(350);
    model = (DefaultTableModel) this.jTable1.getModel();
    model.setNumRows(0);
    }

    Este método nos permite configurar el “DefaultTableModel”, la cual nos da la posibilidad de introducir y recuperar datos de la tabla. Se llama desde el método “arranque()”.

    Método “nuevo()”.
    Código Java
    public void nuevo(){
    this.nuevo.setEnabled(false);
    this.guardar.setEnabled(true);
    this.des.setEnabled(true);
    this.id.setText("Auto");
    }

    Es un método que llamamos desde el botón “Nuevo”, la cual nos habilita los campos necesarios para cargar datos. Recuerden que para botones siempre utilizamos el “Evento” “ActionPerformed”.

    Método cargarTabla();
    Código Java
    public void cargarTabla(){
    st.beginTransaction();
    List<Tipo> lista = (List<Tipo>)st.createQuery("From Tipo").list();
    for (Iterator<Tipo> it = lista.iterator(); it.hasNext();) {
    Tipo tipo = it.next();
    model.addRow(new Object[]{
    tipo.getId(),tipo.getDes()
    });

    }

    En este método utilizamos el “st.beginTransaction()”, la cual nos posibilita iniciar una transacción para almacenar o recuperar datos del MySQL. En la siguiente línea vemos el procedimiento que se utiliza normalmente para recuperar datos de una tabla, utilizando “List”. Con un “for” accedemos a esos datos y con la variable “model” del “DefaultTableModel” utilizando el método “addRow” agregamos registros en la tabla. Se llama desde el método “arranque()”.

    Método “guardar()”.
    Código Java
    public void guardar(){
    if(this.des.getText().isEmpty()){
    JOptionPane.showMessageDialog(null, "Imposible guardar campo vacio.");
    }
    else{
    if(this.guardar.getText().equals("Guardar")){
    st.beginTransaction();
    Tipo t = new Tipo();
    t.setDes(this.des.getText());
    st.save(t);
    st.getTransaction().commit();
    JOptionPane.showMessageDialog(null, "Registro guardado.");
    arranque();
    }
    else{
    st.beginTransaction();
    int selectedRow = this.jTable1.getSelectedRow();
    Object valueAt = model.getValueAt(selectedRow, 0);
    int idTipo = Integer.parseInt(valueAt.toString());
    Tipo t = (Tipo) st.load(Tipo.class, idTipo);
    t.setDes(this.des.getText());
    st.update(t);
    st.getTransaction().commit();
    JOptionPane.showMessageDialog(null, "Registro actualizado.");
    arranque();
    }
    }
    }

    Hacemos una captura para poder explicar a mayor detalle, ya que este método es la que nos permitirá almacenar y actualizar datos dentro del MySQL. (img. 11)


    (Img. 11)
  • (1) Comprobamos que el “JTextFields” cuyo nombre de variable es “des”, no este vacía.
  • (2) Comprobamos que el “caption” del botón guardar sea “Guardar”, pues esta puede tomar dos valores, “Actualizar” y “Guardar” según el caso.
  • (3) Iniciamos una transacción.
  • (4) Creamos un objeto de la clase Tipo. “Tipo” es un clase persistente, al crear una instancia y asignarle valor a sus variables estamos creando un registro en MySQL.
  • (5) Asignamos valor a la variable “des” de la clase persistente “Tipo” con el “método setter” de la misma.
  • (6) Usamos el método “save()” de la Sesión pasando como argumento la clase Tipo que instanciamos.
  • (7) Hacemos un “st.getTransaction().commit();” para confirmar la transacción. Como vieron el procedimiento es totalmente orientado a objetos. No recurrimos al SQL, pues el Hibernate se encarga de negociar con la Base de Datos.
  • (8) Le decimos al usuario que los datos fueron guardados.
  • (9) Llamamos al “método arranque()” para restablecer el formulario y poder iniciar el proceso nuevamente.
  • (10) Utilizamos el “else” en caso que no se den las condiciones del “if”.
  • (11) Las siguientes líneas nos permiten recuperar el “id”, pues como indicamos arriba, en caso que de que el “caption” del botón guardar no sea “Guardar” querrá decir que es “Actualizar”. Como sabemos solamente los registros que ya estén guardados se pueden actualizar.
  • (12) Para recuperar un registro normalmente utilizamos el método “load”, pasándole como argumente la clase y el “id” de la misma, que recuperamos más arriba.
  • (13) Asignamos valor nuevo a la variable “des” de la clase persistente “Tipo” con el “método setter” de la misma.
  • (14) Utilizamos un “update” a diferencia de la anterior.
  • (15) Confirmamos la transacción.
  • (16) Indicamos al usuario que el proceso fue exitoso.

    El método “guardar” se llama desde el botón “Guardar” con el “Evento” “ActionPerformed”.

    Método “obtenerTabla()”.
    Código Java
    public void obtenerTabla(){
    int selectedRow = this.jTable1.getSelectedRow();//Obtenemos la fila seleccionada...
    Object valueAt = model.getValueAt(selectedRow, 0);//Obtenemos el valor de esa fila...
    int idTipo = Integer.parseInt(valueAt.toString());//Convertimos el valor en entero...
    Tipo t = (Tipo) st.load(Tipo.class, idTipo);//Hacemos un load pasando como argumento la clase Tipo y el Id del mismo...
    this.id.setText(String.valueOf(t.getId()));//Asignamos valor al JTextField id.
    this.des.setText(t.getDes());//Asignamos valor al JTextField des.
    this.editar.setEnabled(true);//Activamos el botón editar...
    this.eliminar.setEnabled(true);//Activamos el botón eliminar...
    this.nuevo.setEnabled(false);//Desactivamos el botón nuevo...
    this.guardar.setText("Actualizar");//Cambiamos el de guardar...
    }

    Este método la llamamos desde el “Evento Mouse” – “MouseClicked” del JTable1. Con esto cada vez que el usuario haga clic sobre una de las fila de la tabla se pueda recuperar el valor y pasarlos a los “JTextFields” correspondientes. Las explicaciones desde ahora, dentro de código fuente de forma comentada.

    Método “editar()”.
    Código Java
    public void editar(){
    this.guardar.setEnabled(true);//Activamos botón gurdar...
    this.des.setEnabled(true);//Activamos JTextField des...
    this.eliminar.setEnabled(false);//Desactivamos botón eliminar
    this.jTable1.setEnabled(false);//Desactivamos el JTable
    }

    El método “guardar” se llama desde el botón “Editar” con el “Evento” “ActionPerformed”.

    Método “eliminar()”.
    Código Java
    public void eliminar(){
    int seleccion = JOptionPane.showConfirmDialog(null,"Desea eliminar el Registro.", "Eliminación de Registro.", JOptionPane.YES_NO_OPTION);//Obtnemos la selección del usuario
    if(seleccion == 1){//Comparamos la selección del usuario igual a 1 no eliminamos, si es diferente se elimina.
    JOptionPane.showMessageDialog(null, "Registro no Eliminado...");
    arranque();//Si no se elimina se llama al metodo arranque() para limpiar campos
    }
    else{//Opción eliminar seleccionada
    st.beginTransaction();//Iniciamos transacción
    int selectedRow = this.jTable1.getSelectedRow();//Obtenemos selección
    Object valueAt = model.getValueAt(selectedRow, 0);//Recuperamos valor
    int idTipo = Integer.parseInt(valueAt.toString());//Convertimos valor en entero
    Tipo t = (Tipo) st.load(Tipo.class, idTipo);//Hacemos un load pasando como argumento la clase Tipo y el Id del mismo...
    st.delete(t);//Utilizamos delete pasando como argumento el objeto Tipo que cargamos con load...
    st.getTransaction().commit();//Confirmamos la transacción...
    JOptionPane.showMessageDialog(null, "Registro Eliminado...");//Indicamos al usuario que el proceso fue exitoso...
    arranque();//Limpiamos campos con el metodo arranque()...
    }
    }

    El método “eliminar” se llama desde el botón “Eliminar” con el “Evento” “ActionPerformed”.

    Observación: El método para informe, lo dejamos para lo último del proyecto, ya que requiere utilizar el iReport.


    En esta última imagen vemos el formulario en ejecución y funcionando. (Img. 12)


    (Img. 12)

    Obs.: Resulta difícil explicar todo el proceso y función de cada línea de código por tanto pueden realizar un comentario con sus dudas.


  • 42 comentarios :

    1. HOla, tengo una duda, como puedo eliminar un resgistro de la base de datos mysql, no me queda claro si al seleccionar la fila te trae la posisión pero no el id que esta en la base de datos.

      Como lo hago ????.

      Saludos.

      ResponderEliminar
    2. Que tal amigo, como esta en el ejemplo, se selecciona el elemento a eliminar de la tabla. Seguidamente obtenemos la fila seleccionada con “getSelectedRow()”, recuperamos el valor de la columna “0” el cual almacena el “id”; con el “id” utilizamos un load para cargar el objeto “Tipo” correspondiente y poder eliminarlo. Espero te haya aclarado la duda.

      ResponderEliminar
    3. Gracias me fue de mucha utilidad tu respuesta y sobretodo tu ejemplo.

      Saludos.

      ResponderEliminar
    4. Que hace el metodo setDes de la clase persistente Tipo?

      ResponderEliminar
    5. Hola Carlos, como seria si deseamos tener el formulario de ingreso de datos en otra ventana? Y como podemos manejar dos listas padre e hijos con sus respectivos formularios.

      gracias por tu tiempo

      ResponderEliminar
      Respuestas
      1. Que tal amigo, yo suele usar el elemento visual Dialog que se encuentra en la Paleta en modo diseño. Al agregar se maneja igual que otro formulario, solo que es dependiente del formulario padre. Esto te sirve también para manejar lista en formularios diferentes pero con cierta dependencia. El elemento se maneja como cualquier otro objeto del formulario. Ej., para llamar desde el padre a otro formulario Dialog. Se puede hacer desde un botón creando un método. Espero te sirva.
        ListAsiento.setLocationRelativeTo(null);
        ListAsiento.setModal(true);
        ListAsiento.setMaximumSize(new Dimension(800, 600));
        ListAsiento.setMinimumSize(new Dimension(480, 360));
        ListAsiento.setVisible(true);

        Eliminar
    6. Una consulta amigo ,,, despues de crear un abm y ejecutarlo ya deberia de funcionar..... o funciona solamente cuando uno lo llama desde el formulario principal... gracias!

      ResponderEliminar
      Respuestas
      1. Que tal amigo, cada formulario se puede ejecutar de forma independiente. Clic derecho sobre el formulario para ejecutar...

        Eliminar
    7. Es que me da un error al ejercutar los abm....... algo asiiii...porque podria ser ese error.... Saludos

      "oct 13, 2015 11:47:51 AM org.hibernate.cfg.Environment
      Información: Hibernate 3.2.5
      oct 13, 2015 11:47:51 AM org.hibernate.cfg.Environment
      Información: hibernate.properties not found
      oct 13, 2015 11:47:51 AM org.hibernate.cfg.Environment buildBytecodeProvider
      Información: Bytecode provider name : cglib
      oct 13, 2015 11:47:51 AM org.hibernate.cfg.Environment
      Información: using JDK 1.4 java.sql.Timestamp handling
      oct 13, 2015 11:47:52 AM org.hibernate.cfg.Configuration configure
      Información: configuring from resource: /hibernate.cfg.xml
      oct 13, 2015 11:47:52 AM org.hibernate.cfg.Configuration getConfigurationInputStream
      Información: Configuration resource: /hibernate.cfg.xml
      oct 13, 2015 11:47:53 AM org.hibernate.cfg.Configuration doConfigure
      Información: Configured SessionFactory: null
      oct 13, 2015 11:47:53 AM org.hibernate.cfg.AnnotationBinder bindClass
      Información: Binding entity from annotated class: com.entidades.Tipo"

      ResponderEliminar
      Respuestas
      1. Yo creo que esto que pones (aunque te salga en rojo) no es un error, es INFORMACIÓN, como ahí te lo indica.

        Saludos

        Eliminar
      2. Que tal, ya tienes todas las entidades creadas, parece ser un problema de relación. En el tutorial 004 estan las claves para que las relaciones funcionen. Hay clases entidades dependientes.

        Eliminar
    8. Hola, estoy siguiendo el tutorial y hasta el momento todo bien, pero al intentar guardar el primer registro en Tipo de Articulo, me lanza la siguiente excepción:
      st.beginTransaction();

      Y me dirige a la línea del método guardar() donde se inicia la Transacción:
      st.beginTransaction();

      He estado buscando sobre esta excepción, pero no encuentro nada para solucionalo.
      ¿Qué crees que puede suceder?

      Muchas gracias por todo, un saludo.

      ResponderEliminar
      Respuestas
      1. Que tal, podrías ver si están los métodos que arrancan con el formulario. En la imagen 8 de arriba están las que hay que agregar en el constructor. Puedes copiar el error que manda si no logras solucionar.

        Eliminar
      2. Hola, en el constructor tengo lo siguiente:

        super(parent, modal);
        initComponents();
        sessionHibernate();
        arranque();
        setLocationRelativeTo(null);

        Y el error que me da es el siguiente:

        Eliminar
      3. Exception in thread "AWT-EventQueue-0" org.hibernate.TransactionException: nested transactions not supported
        at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:154)
        at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1431)
        at com.app.TipoApp.guardar(TipoApp.java:411)
        at com.app.TipoApp.guardarActionPerformed(TipoApp.java:277)
        at com.app.TipoApp.access$300(TipoApp.java:24)
        at com.app.TipoApp$4.actionPerformed(TipoApp.java:151)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
        at java.awt.Component.processMouseEvent(Component.java:6505)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
        at java.awt.Component.processEvent(Component.java:6270)
        at java.awt.Container.processEvent(Container.java:2229)
        at java.awt.Component.dispatchEventImpl(Component.java:4861)
        at java.awt.Container.dispatchEventImpl(Container.java:2287)
        at java.awt.Component.dispatchEvent(Component.java:4687)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
        at java.awt.Container.dispatchEventImpl(Container.java:2273)
        at java.awt.Window.dispatchEventImpl(Window.java:2719)
        at java.awt.Component.dispatchEvent(Component.java:4687)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
        at java.awt.EventQueue.access$200(EventQueue.java:103)
        at java.awt.EventQueue$3.run(EventQueue.java:694)
        at java.awt.EventQueue$3.run(EventQueue.java:692)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
        at java.awt.EventQueue$4.run(EventQueue.java:708)
        at java.awt.EventQueue$4.run(EventQueue.java:706)

        Eliminar
      4. at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:154)
        at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:182)
        at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:221)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:219)
        at java.awt.Dialog.show(Dialog.java:1082)
        at java.awt.Component.show(Component.java:1651)
        at java.awt.Component.setVisible(Component.java:1603)
        at java.awt.Window.setVisible(Window.java:1014)
        at java.awt.Dialog.setVisible(Dialog.java:1005)
        at com.app.TipoApp$8.run(TipoApp.java:333)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
        at java.awt.EventQueue.access$200(EventQueue.java:103)
        at java.awt.EventQueue$3.run(EventQueue.java:694)
        at java.awt.EventQueue$3.run(EventQueue.java:692)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

        Eliminar
      5. El error se da cuando se intenta hacer más de una transacción al mismo tiempo, verifica el método de guardado, quizas en alguna parte falte o sobre código. Saludos.

        Eliminar
      6. Hola, el método guardar es el siguiente

        public void guardar(){
        if(this.des.getText().isEmpty()){
        JOptionPane.showMessageDialog(null, "Imposible guardar campo vacio.");
        }
        else{
        if(this.guardar.getText().equals("Guardar")){
        st.beginTransaction();
        Tipo t = new Tipo();
        t.setDes(this.des.getText());
        st.save(t);
        st.getTransaction().commit();
        JOptionPane.showMessageDialog(null, "Registro guardado.");
        arranque();
        }
        else{
        st.beginTransaction();
        int selectedRow = this.jTable1.getSelectedRow();
        Object valueAt = model.getValueAt(selectedRow, 0);
        int idTipo = Integer.parseInt(valueAt.toString());
        Tipo t = (Tipo) st.load(Tipo.class, idTipo);
        t.setDes(this.des.getText());
        st.update(t);
        st.getTransaction().commit();
        JOptionPane.showMessageDialog(null, "Registro actualizado.");
        arranque();
        }
        }
        }

        Eliminar
      7. El codigo de guardado esta bien. Utilizas una versión reciente del hibernate que requiere un porción de código extra en algunos métodos. Al final de cada transacción (st.beginTransaction();) agrega st.getTransaction().commit();.
        El problema que marcas se origina en el método cargarTabla(), que debe ir de la siquiente forma para solucionar el problema.
        public void cargarTabla(){
        st.beginTransaction();
        List lista = (List)st.createQuery("From Tipo").list();
        for (Iterator it = lista.iterator(); it.hasNext();) {
        Tipo tipo = it.next();
        model.addRow(new Object[]{
        tipo.getId(),tipo.getDes()
        });

        }
        st.getTransaction().commit();//Agregar esta porción de código para cerrar la transacción.
        }

        Eliminar
      8. Perfecto!!! Ahora si funciona, muchas gracias por tu ayuda. Seguiré con el tutorial y te iré contando.
        Saludos

        Eliminar
      9. Me alegra que te sea de ayuda, saludos y suerte.

        Eliminar
    9. Por las dudas no hay algun scritp de la base de datos.

      ResponderEliminar
      Respuestas
      1. No amigo, solo se crea la Base de Datos. El hibernate se encarga de crear las tablas y las relaciones según se indica en las clases persistentes. Si persiste el error hay que ver si el alguna cuestión de versiones del Netbeans, para este tutorial utilice el 7.0.

        Eliminar
    10. OK MUCHAS GRACIAS AMIGO .. esta super .. exitos
      No algun tutorial sin el hirbenate .. pero con. Base de datos mysql

      ResponderEliminar
      Respuestas
      1. En este blog no tengo ningún tutorial de ABM con SQL. Disculpa que no te pueda ayudar, saludos.

        Eliminar
    11. Tranquilo esta super amigo .. ya me funciona.. esta super .. lo unico que quiero saber es si con este metodo del hirbenate .. puedo lograr hacer un sistema grande con login, permisos ect y lo esencial si es seguro ..

      ResponderEliminar
      Respuestas
      1. Que tal amigo me alegra que te funciones. El hibernate es bastante flexible y completo, no hay ninguna restricción para lograr un sistema grande y funcional. Yo pude completar un sistema contable con todos los elementos que mencionas. Es cuestión de ir ampliando las posibilidades con esta herramienta. Saludos.

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

      ResponderEliminar
    13. Este comentario ha sido eliminado por el autor.

      ResponderEliminar
    14. Hola Carlos, espero que estés bien. Fijate que me aparece éste error cuando quiero guardar otro registro:


      Exception in thread "AWT-EventQueue-0" org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.entities.Tipo#0]
      at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
      at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:137)
      at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
      at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
      at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
      at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
      at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
      at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:711)
      at org.hibernate.internal.SessionImpl.save(SessionImpl.java:703)
      at org.hibernate.internal.SessionImpl.save(SessionImpl.java:698)

      ResponderEliminar
      Respuestas
      1. He hecho de todo, pero no he podido remediarlo. ¿Que puedo hacer?. Gracias de antemano. :)

        Eliminar
      2. Que tal. Verifica que el inicio de transacción st.beginTransaction(); tenga un cierre después de terminar cada proceso (st.getTransaction().commit();) ya que las nuevas versiones de hibernate la requieren. También mira que no estes confundiendo el Save con el Update, guardado y actualizado que funcionan diferente. Saludos.

        Eliminar
      3. Lo probaré, y luego te aviso. Gracias.

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

        Eliminar
    15. public void guardar(){
      if(this.des.getText().isEmpty()){
      JOptionPane.showMessageDialog(null, "Falta nombre/s del Estudiante.");
      }

      else{
      if(this.guardar.getText().equals("Guardar")){
      st.beginTransaction();
      Tipo t = new Tipo();
      t.setDes(this.des.getText());
      st.save(t);
      st.getTransaction().commit();
      JOptionPane.showMessageDialog(null, "Registro guardado correctamente.");
      arranque();
      }
      else{
      st.beginTransaction();
      int selectedRow = this.jTable1.getSelectedRow();
      int idTipo = Integer.parseInt(String.valueOf(model.getValueAt(selectedRow, 0)));
      Tipo t = (Tipo)st.load(Tipo.class, idTipo);
      t.setDes(this.des.getText());
      st.update(t);
      st.getTransaction().commit();
      arranque();
      JOptionPane.showMessageDialog(null, "Registro actualizado correctamente.");
      }

      }

      }



      }

      ResponderEliminar
      Respuestas
      1. Éste es mi código. Pero aún no he podido insertar otro registro :(

        Eliminar
      2. Según parece por este mensaje "hibernate.NonUniqueObjectException" podrías estar queriendo guardar un registro con el mismo id. El id para tu clase es autoincremental supongo, podría estar mal. El código de guardado parece estar bien. Saludos.

        Eliminar
      3. No lo tenía autoincremental, voy a probar.

        Eliminar
      4. Ya me funcionó, muchisisisimas gracias por tu ayuda amigo. Bendiciones para tí.

        Eliminar
      5. Me alegra que sirva. Saludos y suerte.

        Eliminar
    16. Hola estimado Carlos, muy buen tutorial, lamentablemente no me funciona, quizas sea por mi version yo stoy con netbeans 8.2 y postgre pgadmin 4, he tenido que cambiar el script del hibernate.util ala version para netbeans 8.2, me cargan las tablas cuando corrro el programa pero a la vez me aparecen muchisimas lineas de consola en rojo (errores) y no me funciona ningun proceso (guardar, eliminar, update)
      ahhh y mi codigo lo he cambiado las lineas st = HibernateUtil.getSessionFactory().openSession(); por st = HibernateUtil.createSessionFactory().openSession(); porque en mi version el getSessionFactory no existe, puede ser ese el problema? me podrías ayudar?

      ResponderEliminar