2012-03-26 3 views
6

Ich habe gerade ein interessantes Problem.Vaadin und Hibernate - Schließen Sie die Verbindung zur Datenbank korrekt

Meine Situation:

  • ich zur Zeit einen Web-Service entwickle (Ich bin in Eclipse für die Programmierung mit JAVA Vaadin verwenden)
  • Meine Datenbank hinter Java-Derby
  • Ich verwende ist hibernate für meine Datenbank
  • ich zur Zeit es v7.0 auf Tomcat bereitstellen bin

Mein Problem:

  • Wenn ich etwas in meinem Code (egal was) zu ändern, sollte der Server es ohne die Notwendigkeit nachladen neu gestartet werden - ich denke, das ist das gesamte erwartete Verhalten
  • Die Server lädt die Anwendung erfolgreich neu, aber wenn ich versuche, etwas anzuklicken (also nach dem Neuladen), z die Login-Taste, bekomme ich einen Fehler

Fehlermeldung:

Ursache: org.hibernate.exception.GenericJDBCException: nicht Verbindung öffnen konnte] mit Ursache ERROR XSDB6: Eine andere Instanz von Derby Mai haben bereits die Datenbank C: \ HTML-Ausgabe \ Datenbank \ DocumentDB gestartet. bei org.apache.derby.iapi.error.StandardException.newException (Unbekannt Source) ...

Meine Gedanken zu diesem

Es scheint, dass irgendwie auf dem Nachladen Prozess die Verbindung/Kontext zu überwintern doesnt bekommen zerstört/geschlossen und so die Fehler occures, wenn der Server mit der Datenbank zu verbinden versucht

My-Code

ich eine Klasse, die so genannten Ruhe Zuhörer:

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 
    } 
} 

Mein 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> 

My (Vaadin) web.xml, in dem ich einen "Hörer" für die zugegebenen

<?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> 

ich habe Forschung, auch gepostet hat leider ein passendes Thema auf diesem w (ohne auch nur eine einzige Antwort :(noch) und jetzt auf dem Hibernate-Forum: obere HibernateListener (überprüfen Sie den Text im Hörer) gezeigt ebsite. Also ich hoffe, ich habe nichts falsch gemacht.

Wenn jemand von mir irgendwie helfen könnte, wäre ich wirklich glücklich. Derzeit weiß ich nicht, was ich ändern soll, um diesen Fehler zu vermeiden. Und natürlich kann ich den ganzen Server später nicht immer neu starten, wenn meine Anwendung im Internet ist, wenn ich eine Codezeile ändere.

Vielen Dank für jede Antwort und dachte, dass Sie mit mir teilen.

Antwort

4

fand ich die Lösung für mein Problem.

Zunächst einmal war es ein Apache Derby Problem, wie ich sie gezwungen, mit

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

es funktionierte gut zu schließen.

Nun habe ich meine Datenbank vom Apache Derby nach mysql geschalten und festgestellt, dass das Problem, das in meiner Frage oben beschrieben wurde, nicht mehr auftrat.

Also, Lektion gelernt: Verwenden Sie nicht Apache Derby. Ich hoffe, das hilft einem anderen irgendwann. Vielen dank für Deine Hilfe.

+0

Yea Ich benutze HyperSQL, wenn ich eine In-Memory-DB während des Entwickelns brauche. Hat mir nie Probleme gemacht. – anataliocs

2

Schnelle und schmutzige Lösung: Eine schnelle und dreckige temporäre Lösung könnte nur sein, um "neustartApplication" überall dort anzuhängen, wo Ihre Vaadin-Anwendung verbunden ist.

Bessere Lösung: Ich empfehle die Verwendung der Sitzung-pro-Anfrage-Muster mit Hibernate. Indem Sie den Transaktions-Listener von Vaadin verwenden, können Sie leicht sicherstellen, dass die Sitzung bei jeder Anfrage geschlossen wird, ohne unseren Programmcode mit zusätzlicher Logik zu belasten.

Sie platzieren diese Methoden in Ihrer Hauptanwendungsmethode und führen dann in Ihrer init() -Methode attachVaadinTransactionListener() aus. Link zum detaillierten Artikel dazu unten.

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

Eine schnelle und dreckige temporäre Lösung könnte einfach sein, um "neustartApplication" überall dort anzuhängen, wo Ihre Vaadin-Anwendung verlinkt ist. – anataliocs