2012-03-26 11 views
6

Actualmente estoy teniendo un problema interesante.Vaadin and Hibernate - Cerrar la conexión a la base de datos correctamente

mi situación:

  • actualmente estoy desarrollando un servicio web (estoy usando vaadin para la programación con Java en Eclipse)
  • Mi base de datos detrás de java es derby
  • estoy usando hibernar durante mi base de datos
  • estoy actualmente desplegarlo en Tomcat v7.0

Mi Problema:

  • Cuando cambio algo en mi código (no importa qué), el servidor debe volver a cargarlo sin la necesidad de ser reiniciado - supongo que es el comportamiento esperado en general
  • El el servidor vuelve a cargar la aplicación con éxito, pero si intento hacer clic en algo (luego de la recarga), por ejemplo el inicio de sesión-Button, me sale un error

mensaje de error:

Causa: org.hibernate.exception.GenericJDBCException: No se pudo abrir la conexión ] con causa raíz XSDB6 ERROR: Otro ejemplo of Derby may ya han arrancado la base de datos C: \ HTML-Ausgabe \ database \ DocumentDB. en org.apache.derby.iapi.error.StandardException.newException (Desconocido Fuente) ...

Mis pensamientos en este

Parece que de alguna manera en el proceso de recarga de la conexión/contexto de hibernación imposible encontrar destruido/cerrado y así occures el error cuando el servidor intenta volver a conectarse a la base de datos

Mi Código

tengo una clase, llamada Hibernate Oyente:

public class HibernateListener implements ServletContextListener { 

    public void contextInitialized(ServletContextEvent event) { 
     HibernateUtil.getSessionFactory(); // Just call the static initializer of that class  
    } 

    public void contextDestroyed(ServletContextEvent event) { 
     HibernateUtil.getSessionFactory().close(); // Free all resources 
    } 
} 

Mi hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-configuration PUBLIC 
     "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
     "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
    <session-factory> 
     <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property> 
     <property name="hibernate.connection.url">jdbc:derby:C:\HTML-Ausgabe\database\DocumentDB;create=true</property> 
     <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property> 
     <property name="hibernate.current_session_context_class">thread</property> 
     <property name="hibernate.hbm2ddl.auto">create-drop</property> 
     <property name="hibernate.show_sql">true</property> 

     <mapping class="view.model.database.User"/> 
     <mapping class="view.model.database.Document"/> 
     <mapping class="view.model.database.Version"/> 
     <mapping class="view.model.database.VersionData"/> 
    </session-factory> 
</hibernate-configuration> 

Mi (vaadin) web.xml, en la que he añadido un "oyente" para la superior muestra HibernateListener (marque el texto en el oyente):

<?xml version="1.0" encoding="UTF-8"?> 
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
    <display-name>Bachelorprojekt</display-name> 
    <context-param> 
     <description>Vaadin production mode</description> 
     <param-name>productionMode</param-name> 
     <param-value>false</param-value> 
    </context-param> 
    <servlet> 
     <servlet-name>Bachelorprojekt Application</servlet-name> 
     <servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class> 
     <init-param> 
      <description>Vaadin application class to start</description> 
      <param-name>application</param-name> 
      <param-value>view.view.WebsiteFrame</param-value> 
     </init-param> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>Bachelorprojekt Application</servlet-name> 
     <url-pattern>/*</url-pattern> 
    </servlet-mapping> 

    <listener> 
     <listener-class>view.model.database.HibernateListener</listener-class> 
    </listener> 
    <welcome-file-list> 
     <welcome-file>index.html</welcome-file> 
     <welcome-file>index.htm</welcome-file> 
     <welcome-file>index.jsp</welcome-file> 
     <welcome-file>default.html</welcome-file> 
     <welcome-file>default.htm</welcome-file> 
     <welcome-file>default.jsp</welcome-file> 
    </welcome-file-list> 
</web-app> 

yo investigación, publicado también en el foro de hibernación (todavía sin ni siquiera una sola respuesta :() y ahora no encuentra un tema de juego en esta w ebsite. Así que espero no haber hecho algo mal.

Si alguno de ustedes me puede ayudar de alguna manera, estaría muy feliz. Actualmente no sé qué cambiar para evitar que ocurra este error. Y, por supuesto, no puedo reiniciar todo el servidor más tarde cuando mi aplicación está en Internet, si cambio una línea de código.

Muchas gracias por cada respuesta y pensé que compartirías conmigo.

Respuesta

4

he encontrado la solución a mi problema.

En primer lugar, se trataba de un problema de Apache Derby, ya que obligó a cerrar con

public void contextDestroyed(ServletContextEvent event) { 
    HibernateUtil.getSessionFactory().close(); // Free all resources 
    try { 
      DriverManager.getConnection("jdbc:derby:;shutdown=true"); 
    } catch (SQLException e) {} 
    } 
} 

funcionó bien para mí.

Ahora cambié mi base de datos vom apache derby a mysql y noté que el problema, descrito en mi pregunta anterior, ya no ocurría.

Entonces, lección aprendida: No use apache derby. Espero que esto ayude a alguien más algún día. Muchas gracias por tu ayuda.

+0

Sí, utilizo HyperSQL cuando necesito un DB en memoria durante el desarrollo. Nunca me ha dado problemas. – anataliocs

2

Solución rápida y sucia: ¿Una solución temporal rápida y sucia podría ser solo anexar? ReiniciarAplicación en cualquier lugar donde se vincule su aplicación Vaadin.

Mejor solución: Recomiendo usar el patrón de sesión por solicitud con Hibernate. Al usar el oyente de transacciones de Vaadin, puede asegurarse fácilmente de que la sesión se cierre en cada solicitud sin contaminar el código de nuestro programa con una lógica adicional.

Coloque estos métodos en su método de aplicación principal y luego ejecute attachVaadinTransactionListener() en su método init(). Enlace al artículo detallado sobre esto a continuación.

private void attachVaadinTransactionListener() { 
    getContext().addTransactionListener(new TransactionListener() { 
     public void transactionEnd(Application application, 
       Object transactionData) { 
      // Transaction listener gets fired for all (Http) sessions 
      // of Vaadin applications, checking to be this one. 
      if (application == EnpApplication.this) { 
       closeSession(); 
      } 
     }   

     public void transactionStart(Application application, 
       Object transactionData) { 
     } 
    }); 
} 

private void closeSession() { 
    Session sess = HibernateUtil.getSessionFactory().getCurrentSession(); 
    if (sess.getTransaction().isActive()) {   
     sess.getTransaction().commit(); 

     if(sess.isOpen()) { sess.flush(); } 
    } 
    if(sess.isOpen()) {   
     sess.close(); 
    } 
} 

Hibernate with Vaadin

+0

Una solución temporal rápida y sucia podría ser simplemente agregar? RestartApplication en cualquier lugar donde esté vinculada su aplicación Vaadin. – anataliocs

Cuestiones relacionadas