Foros del Web » Programación para mayores de 30 ;) » Java »

hibernate - sessiones y excepciones

Estas en el tema de hibernate - sessiones y excepciones en el foro de Java en Foros del Web. Hola. Les hago una consulta. Que pasaria si por ejemplo tubiese el siguiente bloque. Session session = HibernateUtil.getSessionFactory().openSession(); Transaction tx = session.beginTransaction(); User user = ...
  #1 (permalink)  
Antiguo 02/05/2006, 15:50
 
Fecha de Ingreso: marzo-2005
Mensajes: 58
Antigüedad: 19 años, 1 mes
Puntos: 0
hibernate - sessiones y excepciones

Hola. Les hago una consulta. Que pasaria si por ejemplo tubiese el siguiente bloque.

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
User user = (User) session.load(User.class, username);
session.delete(user);
tx.commit();
session.close();

No estoy seguro si este simple delete produciria que hibernate produzca algun bloqueo sobre la tabla o tubla correspondiente que es lo que estoy buscando como ejemplo,de no ser asi suponga que si esta sucediendo (esta bloqueando?).

Bueno, que sucede si una vez que hibernate realizo el bloqueo provoca una excepcion? Antes que nada supongo deberia cerrar la sesion no? con la transaccion que hago? y para desbloquear lo que se bloqueo que hago? Esta ultima pregunta la hago pro que despues de tener este tipo de problemas al intentar acceder por otro lado me he encontrado con que seguia bloqueada y obtenia excepciones del tipo:

Caused by: java.sql.BatchUpdateException: Lock wait timeout exceeded; try
restarting transaction

Desde ya muchas gracias, saludos, pablo.
  #2 (permalink)  
Antiguo 03/05/2006, 10:36
Avatar de mauled  
Fecha de Ingreso: marzo-2005
Ubicación: Cd. de México.
Mensajes: 3.001
Antigüedad: 19 años, 1 mes
Puntos: 33
En el codigo que pones en ¿Donde esta declarado tu variable username? En tu archivo hbm.xml ¿tienes definida la etiqueta <id>? de lo contrario no podras hacer uso de la funcion load().
  #3 (permalink)  
Antiguo 03/05/2006, 14:53
 
Fecha de Ingreso: marzo-2005
Mensajes: 58
Antigüedad: 19 años, 1 mes
Puntos: 0
No si esta defina digamos que es un pseudocodigo. En realidad es el body de un metodo deleteUser que si mal no recuerdo que resive como parametro esa variable.
  #4 (permalink)  
Antiguo 03/05/2006, 15:13
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Si tratas el error como toca y haces un commit o un rollback de la transaccion, entonces el bloqueo debería ser liberado.

Si despues de hacer el bloque ocurre una excepcion y no controlas bien la transaccion y no la cierras, entonces se quedaría bloqueado el registro.

EJB con CMT controla automaticamente las transacciones al llamar a metodos, pero Hibernate no, asi que hay que hacer un buen tratamiento, similar al que se hace para cerrar las conexiones a bases de datos o devolverlas a pools de conexiones.

Un saludo
  #5 (permalink)  
Antiguo 07/05/2006, 05:12
 
Fecha de Ingreso: marzo-2005
Mensajes: 58
Antigüedad: 19 años, 1 mes
Puntos: 0
GreenEyed: Todas las excepciones que larga hibernate son subclases de HibernateExecutionException? Hay alguna raiz de todas las excepciones? donde puedo leer hacerca del api de hibernate?

gracais, saludos, pablo.
  #6 (permalink)  
Antiguo 07/05/2006, 09:44
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Para la documentación, aquí: http://www.hibernate.org/5.html

En cuanto a las excepciones, creo que todas heredan de HibernateException. O si no haz un capturar Exception (no subas hasta Throwable) y así te aseguras de pillar cualquier cosa y cerrar la transaccion siempre.

Lo mejor es encapsular todo el tratamiento en una clase y reutilizarlo por todo, asi no te olvidas nunca de tratar ese caso que luego hace que falle la cosa.

<S>

Yo uso algo tal que así:
Código:
    // Get the session
    Session theSession = null;
    Transaction theTX = null;
    try
    {
      theSession = factory.openSession();
      theTX = theSession.beginTransaction();
      boolean error = false;
      try
      {
        // Ejecucion de las acciones con la sesion Hibernate
        //...
        //...
      }
      catch (Exception e)
      {
       error = true;
       // Informar de error
      }
      if (error && theTX != null)
      {
        try
        {
          theTX.rollback();
        }
        catch (HibernateException he)
        {
         // Informar de error haciendo rollback
        }
      }
      else if (theTX != null)
      {
        try
        {
          theTX.commit();
        }
        catch (HibernateException he)
        {
         // Informar de error haciendo commit
        }
      }
    }
    catch (HibernateException e)
    {
      // Informar de error obteniendo la sesion
    }
    finally
    {
      if (theSession != null)
      {
        try
        {
          theSession.close();
        }
        catch (HibernateException e)
        {
          // Informar de error cerrando la sesión
        }
      }
    }

Última edición por GreenEyed; 07/05/2006 a las 10:42
  #7 (permalink)  
Antiguo 08/05/2006, 07:43
 
Fecha de Ingreso: marzo-2005
Mensajes: 58
Antigüedad: 19 años, 1 mes
Puntos: 0
Gracias de nuevo GreenEyed. Ahora estoy con otro asunto pero luego tengo que volver a esto. Viste la duda sobre el pool de conexiones? tienes idea de como solucioanr el problema o que puede estar pasando?

Algo similar me habia sucedido con otra aplicacion en la que dejaba a tomcat que maneje los controles de acceso a las distantas partes del sitio: y cuando se pasaba mucho tiempo perdia la coneccion y no volvia a conectarse. Como no encontre el problema tube que "parcharlo" agregando un thread que cada tanto tiempo se conecte a la base de datso. Me gustaria en este caso evitar tener que caer el algo parecido y encontrar la causa real y una solucion mas "clara" sin parches.

Bueno, no se si estoy abusando de tu buena voluntad :) Che estoy viendo que participas muchisimo del foro trabajas en esto o es de "onda" que lo haces?

Saludso, pablo.
  #8 (permalink)  
Antiguo 08/05/2006, 13:25
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Ya he visto lo del pool, espero que el enlace que he puesto te sirva.

Trabajar trabajo haciendo aplicaciones en Java, lo de los foros es "por amor al arte", al igual que colaborar en java.net.
  #9 (permalink)  
Antiguo 09/05/2006, 07:01
 
Fecha de Ingreso: marzo-2005
Mensajes: 58
Antigüedad: 19 años, 1 mes
Puntos: 0
Estoy viendo lo del manejo de excepciones. Me decis de encapsular el tratamiento en una clase. Pero en ese caso tendria que caer en una explosion de clases, una para cada tipo de operacion que realice con hibernate. Es asi como lo estas manejando?

Yo sigo con mi tipica curiosidad :) Trabajas para alguna empresa en relacion de dependencia, en officina o por tu cuenta? En realidad te pregunto por que yo estoy trabajando para una empresa espaniola y se me vence el contrato pronto y estoy viendo que hacer. Nada curiosidad nomas.

Última edición por jvagliat; 09/05/2006 a las 08:47
  #10 (permalink)  
Antiguo 09/05/2006, 09:35
 
Fecha de Ingreso: marzo-2005
Mensajes: 58
Antigüedad: 19 años, 1 mes
Puntos: 0
Ademas con el tema de reutilizar el manejo de errores (como bien me dijiste tengo que trabajar con algo asi como exception para tratar todos los errores), pero asi no puedo contemplar excepciones que larga mi logica/mi codigo. Estoy viendo como hacerlo y lo que me sale me resulta engorrozo (mucho laburo y hay mas codigo para el manejo de excepciones que la logica propiamente dicha). Por ejemplo:

Código:
    
public void deleteOffice(String name) throws OfficeWithOrdersException,  OrderServiceException{
     Session session = null;
    Transaction tx = null;
    try{
      session = HibernateUtil.getSessionFactory().openSession();
      tx = session.beginTransaction();

      List offices = session.createQuery(
          "from Office as o where and o.name = \'" + name +
          "\'").list();
      if (offices.isEmpty()) {
        throw new IllegalArgumentException();
      }
      Office office = (Office) offices.get(0);
      java.util.Set orders = office.getOrders();
      if (!orders.isEmpty()) {
        throw new OfficeWithOrdersException();
      }
      session.delete(office);
      tx.commit();
    }catch(IllegalArgumentException e){
      tx.commit();
      throw e;
    }catch(OfficeWithOrdersException e){
      tx.commit();
      throw e;
    }catch(Exception e){
      if (tx!=null) tx.rollback();
      throw new OrderServiceException(e);
    }finally{
      if (session!=null)
        session.close();
    }
  }
}
En este caso puedo largar dos tipos de excepciones OfficeWithOrdersException e IllegalArgumentException. Por un lado en estos casos hago un commit (distinto a cuando sucede algun otro tipo de excepcion). Por otro tengo que manejar esos "tipos" de excepciones para que el codigo que afuera usa a este sepa como actuar. Entonces caigo en tener que catchear todas las que yo lanzo para hacer el commit (en "toda" mi el codigo de mi logica)y lanzar algo de ese tipo (o mandarle a lo chancho un isnstanceOf) para poder contemplar todas las restantes excepciones.

Es asi como digo? Voy a tener que hacer este manejo en cada metodo? Que opinan de lo que estoy haciendo?

Nuevamente gracias por su ayuda, saludos, pablo.
  #11 (permalink)  
Antiguo 09/05/2006, 12:53
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Hola, en cuanto a la encapsulación de ejecuciones en clases para no repetir código, yo lo que tengo es una clase generica donde está el trozo que maneja las transacciones que te enseñe y luego una clase generica mas o menos así:
Código:
  /**
   * Class to perform actions with the hibernate wrapping
   */
  public static abstract class HBAction
  {
    public abstract void perform(Map paramMap, Session theSession,
        Map output, Map errorList);
  }
Entonces cuando quiero ejecutar algo, lo que hago es crear una instancia de esa clase con el codigo que me interesa. En tu caso, seria algo asi como esto:
Código:
  public static HBAction deleteOffice = new HBAction()
  {
    public void perform(Map paramMap, Session theSession,
        Map output, Map errorList)
   {
     String name = (String) paramMap.get("p_name");
     if ((name != null) && (name.trim().length() > 0))
     {
       // Realizar el query. NUNCA usar directamente parametros sin tratar
       // concatenandolos para construir sentencias
        try
        {
         List offices = session.createQuery("from Office as o where and o.name = ?").setString(0,name).list();
         if (!offices.isEmpty())
         {
           Office office = (Office) offices.get(0);
           if(office.getOrders()==null || office.getOrders().isEmpty())
           {
             session.delete(office);
             session.flush;
           }
           else
           {
           errorList.put(OFFICE_WITH_ORDERS_ERROR,"No se puede borrar una oficina con ordenes pendientes: " + name);
           }
         }
         else
         {
           errorList.put(NO_OFFICE_NAME_ERROR,"No existe una oficina con el nombre: " + name);
         }
        }
        catch (HibernateException e)
        {
           errorList.put(DATABASE_ERROR,"Error borrando la oficina con ordenes pendientes: " + name);
           errorList.put(DATABASE_ERROR_EXCEPTION,e);
        }
     }
      else
     {
       errorList.put(NO_NAME_ERROR,"Parametro name obligatorio");
     }
   }
  }
La clase que te envie, lo que hace es que tu le pasas un/varios HBAction y los ejecuta (donde ponia "Ejecucion de las acciones con la sesion Hibernate") y en vez un booleano de error, lo que compruebo es que el Map errorList este vacio al acabar de ejecutar las acciones. Si esta vacio, commit. Si no, rollback. En caso de querer devolver objetos (una consulta en vez de un borrado) se pondrían en el Map output y se recogen al salir (si usas Hibernate y lazy loading hay que tener cuidado con lo que haces con ellos fuera de la transaccion).

Yo en vez de objetos uso XML, asi que en vez de Maps yo paseo nodos de XML y no tengo problemas al usar los objetos una vez se ha acabado la transaccion. Así que este codigo es adaptado un poco a ojimetro y puede contener errores, el original para XML lo puedes ver aqui:
https://webleaf.dev.java.net/source/....1&view=markup

En cuanto a relacion de codigo/tratamiento de errores. A mi no me suele preocupar mucho mientras sea claro de leer y facil de mantener. En ese sentido suelo ser muy verborreico pero tengo programas en marcha 24h/dia que no he tocado en años y cuando hay un error miro los logs y se exactamente lo que pasa. Además que este tipo de planteamiento de hacer codigo "simplon" permite más adelante dejar que te lo genere automaticamente el ordenador para ciertos casos .

Una recomendación es no usar nunca excepciones para controlar el flujo de tu programa, como estas haciendo en tu ejemplo para señalar que un parametro no esta o que un query no devolvio nada. Las excepciones son normalmente para errores graves no previstos para no confudir las cuestiones "leves", que un query no devuelva nada puede ser bien normal, de las "graves", como que la BDD no está accesible o que el SQL dio un error.

En cuanto a trabajar, trabajo en una universidad en departamento de desarrollo interno (no como profe) y algunas tardes como consultor para empresas con "problemillas" en sus aplicaciones web. Es una buena combinacion para mi gusto.

Un saludo

Nota: El codigo asi como esta no funciona directamente, esta puesto un poco a ojo adaptado del que uso .
  #12 (permalink)  
Antiguo 12/05/2006, 05:58
 
Fecha de Ingreso: marzo-2005
Mensajes: 58
Antigüedad: 19 años, 1 mes
Puntos: 0
La verdad que no das clases pero sos un maestro...

... de todos modos hay algunas cosas que no si si no comparto o no me terminan de cerrar. Como en los ultimos mensajes estoy medio apremiado de tiempo por que tengo unos plazos muy cortos que se me vienen encima :). Me gustaria plantearte algujnas cosas ya que me dejaste pensando...

despues vuelvo, gracias, pablo.
  #13 (permalink)  
Antiguo 29/05/2006, 09:26
 
Fecha de Ingreso: marzo-2006
Mensajes: 11
Antigüedad: 18 años, 1 mes
Puntos: 0
Hola, estoy empezando a trabajar con Hibernate y el resultado hasta el momento es un monton de excepciones.

Realice un ejemplo creando una Clase de prueba con un codigo y una descripcion, su mapping utiliza una sequencia para el codigo y la base es Postgres 8.1 el driver que utilizo es postgresql-8.1-404.jdbc3.jar.

El problema se me plante cuando relizo un save() y la hacer el commit de la transaccion tira esta exception

Hibernate: select nextval ('sq_pruebas')
Hibernate: insert into PRUEBA (DESCRIPCION, CODIGO) values (?, ?)
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert( SQLStateConverter.java:59)


Si alguien tubo este problema y lo puede explicar, estaremos muy agradecidos.

Saludos
  #14 (permalink)  
Antiguo 11/06/2008, 04:04
 
Fecha de Ingreso: junio-2008
Mensajes: 5
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: hibernate - sessiones y excepciones

Hola a todos:
nesitaria que me ayudaran...

Estoy desarrollando una aplicacion con acceso a datos a traves de Hibernate y necesito acceder a una base de datos (distinta a la que tengo en el xml de configuracion) y que esta hubicada en otro servidor distinto al de las bd a la que me conecto.


no quiero establecer una nueva conexion... He probado con haciendo la select directamente en el mapping con un alias, ejecutando un procedimiento que hace una select de la tabla en cuestion, he creado una vista de dicha tabla, y recupero los datos de dicha vista a traves de un procedimeinto almacenado.... he probado mil cosas y la unica solucion que he encontrado es crear otra conexion y abrirla justo en el momento que necesito la consulta y cerrarla de inmediato porque todos mi mapeos tiran de la bd a la que me conecto de inicio...

Tiene alguien una solucion que no conlleve hacer una nueva conexioon???????
gracias por su ayuda de antemano
  #15 (permalink)  
Antiguo 29/03/2011, 15:44
 
Fecha de Ingreso: marzo-2011
Mensajes: 1
Antigüedad: 13 años, 1 mes
Puntos: 0
Respuesta: hibernate - sessiones y excepciones

Cita:
Iniciado por amy_tekno Ver Mensaje
Hola a todos:
nesitaria que me ayudaran...

Estoy desarrollando una aplicacion con acceso a datos a traves de Hibernate y necesito acceder a una base de datos (distinta a la que tengo en el xml de configuracion) y que esta hubicada en otro servidor distinto al de las bd a la que me conecto.


no quiero establecer una nueva conexion... He probado con haciendo la select directamente en el mapping con un alias, ejecutando un procedimiento que hace una select de la tabla en cuestion, he creado una vista de dicha tabla, y recupero los datos de dicha vista a traves de un procedimeinto almacenado.... he probado mil cosas y la unica solucion que he encontrado es crear otra conexion y abrirla justo en el momento que necesito la consulta y cerrarla de inmediato porque todos mi mapeos tiran de la bd a la que me conecto de inicio...

Tiene alguien una solucion que no conlleve hacer una nueva conexioon???????
gracias por su ayuda de antemano
Tienes que tener otro proyecto web.
Crea un proyecto java aplication es decir un proyecto .jar y lo incluyes en tu proyecto anterior. Ese proyecto lo configuras para conectarte a la nueva base de datos. y luego lo incluyes en tu proyecto anterior(el que mencionas) y crear las rutinas hibernate para esa nueva aplicación.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 21:58.