Vaadin and Hibernate - Close database connection properly

I'm currently having an interesting problem.

My situation:

  • I am currently developing a web service (I am using VAADIN for programming with JAVA in eclipse).
  • My database is java derby
  • I use hibernate for my database
  • I am currently posting it on Tomcat v7.0

My problem:

  • When I change something in my code (it doesn’t matter what), the server should restart it without the need to restart - I think the general expected behavior
  • The server restarts the application successfully, but if I try to click something (so after the reboot), for example, the login button, I get an error message

Error message:

Reason: org.hibernate.exception.GenericJDBCException: could not open the connection] with the main reason ERROR XSDB6: another instance of Derby may already have loaded the database C: \ HTML-Ausgabe \ database \ DocumentDB. at org.apache.derby.iapi.error.StandardException.newException (Unknown Source) ...

My thoughts on this

It seems that somehow during the reboot, the connection / context in hibernate is not destroyed / closed, and therefore an error occurs when the server tries to connect to the database

My code

I have a class called Hibernate Listener:

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

My 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 which I added a "listener" for the top HibernateListener shown (check the text on the listener):

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

I did research on the hibernate forum (still without a single answer :() and now I haven’t found a suitable topic on this website. Therefore, I hope that I didn’t do something wrong.

If any of you could help me, I would be really happy. Currently, I do not know what to change to stop this error. And, of course, I cannot restart the entire server later when my application is on the Internet if I change one line of code.

Thanks so much for every answer and thought you were sharing with me.

+6
source share
2 answers

I found a solution to my problem.

First of all, it was an Apache Derby issue, as I made it close with

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

it worked for me.

Now I dug my vom apache derby database in mysql and noticed that the problem described in my question above no longer occurs.

So, a lesson learned: Do not use apache derby. Hope this one day helps someone else. Many thanks for your help.

+4
source

Quick and dirty solution: Can a quick and dirty temporary solution just be added? restartApplication wherever your Vaadin app is connected.

Best Solution: I recommend using a session template per request with Hibernate. Using the Vaadin transaction listener, you can easily make sure that the session is closed for each request without polluting our program code with additional logic.

You put these methods in your main application method, and then execute attachVaadinTransactionListener () in your init () method. Link to a detailed article on this subject below.

  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(); } } 

Sleep mode with Vaadin

+2
source

Source: https://habr.com/ru/post/911696/


All Articles