2009-09-04 18 views
2

J'ai une webapp avec Spring et cela fonctionne correctement quand j'utilise HSQLDB en mode serveur, mais en mode fichier, il ne passe que le test unitaire. Ceci est ma source de données:Comment intégrer HSQLDB dans un fichier avec Spring à une WebApp

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close"> 
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> 

    <property name="url" value="jdbc:hsqldb:hsql://localhost/images" /> 
    <property name="username" value="sa" /> 
    <property name="password" value="" /> 
</bean> 

Je viens de changer cette ligne

<property name="url" value="jdbc:hsqldb:hsql://localhost/images" />  
    (-- Server mode) 

pour cette

 <property name="url" value="jdbc:hsqldb:file:data/images" />  
    (-- In file) 

Et il passe juste le test unitaire, et échoue dans le APPP Web.

Je suppose qu'en mode fichier, lorsque je lance la webapp, HSQLDB ne trouve pas le fichier de la base de données.

J'ai déjà essayé de mettre les données de la base de données dans la racine de la webapp et dans le web-inf, et cela ne fonctionne pas.

Répondre

0

Vous devez utiliser un chemin de fichier absolu. Lorsque vous exécutez votre application Web, votre répertoire "en cours" (ou "en cours") est probablement le dossier bin de votre serveur d'applications. Par conséquent, lorsque vous spécifiez le chemin relatif pour l'URL HSQLDB, il essaie de charger ce fichier à partir de cet emplacement plutôt que par rapport à votre racine webapp.

1

Je trouve la réponse ici:

http://coding.derkeiler.com/Archive/Java/comp.lang.java.databases/2003-11/0096.html

Je mets de données à l'intérieur dans un pot sur mon projet persistenceLayerWithData.jar.

Puis-je ceci propety à la source de données:

<property name="url" value="jdbc:hsqldb:res:/data/images" /> 

Et j'ajouté le pot sur le Web-INF/lib et de faire la guerre (tout cela avec Maven) et déployer dans tomcat et il fonctionne, aussi je le déploie dans websphere 7 et fonctionne aussi.

Mais quand je lance whit mvn jetty: run je ne suppose pas que lors de l'exécution de jetty whit maven il ne met pas le jar dans le claspath.

+0

Le fichier de base de données est-il dans src/main/resources? Aussi, vous attendez-vous à éditer cette base de données? –

2

Eh bien, si vous mettez la base de données à l'intérieur du pot comme ceci:

<property name="url" value="jdbc:hsqldb:res:/data/images" /> 

Vous ne pouvez l'utiliser comme lecture seule, si vous essayez d'insérer ou de modifier la base de données si échouera.

Une solution consiste à placer un écouteur dans le fichier web.xml. Ainsi, lorsque l'application démarre, elle s'initialise avec le chemin racine du site Web de l'application.

<?xml version="1.0" encoding="UTF-8"?> 
<web-app 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>maf</display-name> 
    <session-config> 
     <session-timeout> 
      30 
     </session-timeout> 
    </session-config> 
    <welcome-file-list> 
     <welcome-file>index.jsp</welcome-file> 
    </welcome-file-list> 


    <!--This is to get root of the aplication--> 

    <listener> 
     <listener-class> 
    org.atoms.HsqlDatabaseListener 
     </listener-class> 
    </listener> 


     <!--Este listener se encarga de inicializar todo el contenedor de Spring y mantener una variable en el 
    ServletContext que apunta a dicho contenedor --> 

    <listener> 
     <listener-class> 
    org.springframework.web.context.ContextLoaderListener 
     </listener-class> 
    </listener> 




</web-app> 

L'auditeur:

package org.atoms; 

import javax.servlet.ServletContext; 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 


/** 
* 
* @author atomsfat 
*/ 
public class HsqlDatabaseListener implements ServletContextListener { 

    private ServletContext context = null; 

    public void contextInitialized(ServletContextEvent event) { 
     context = event.getServletContext(); 

     String prefix = event.getServletContext().getRealPath("/"); 

     System.out.println("database root " + prefix); 
     com.atoms.HsqlDatabasePathResolver.getInstance(prefix); 


    } 

    public void contextDestroyed(ServletContextEvent event) { 
     context = event.getServletContext(); 

    } 

L'autre classe:

package com.atoms; 


/** 
* 
* @author atomsfat 
*/ 
public class HsqlDatabasePathResolver { 


    private static HsqlDatabasePathResolver instance ; 
    private static String applicationPath = ""; 

    private HsqlDatabasePathResolver() { 
    } 

     /** Get Instance. 
    */ 
    static public synchronized HsqlDatabasePathResolver getInstance(String applicationPath) { 

     if (instance == null) { 

      HsqlDatabasePathResolver.applicationPath = 
        HsqlDatabasePathResolver.normalizePath(applicationPath); 
      instance = new HsqlDatabasePathResolver(); 



      System.out.println("Inizalizando path : " + HsqlDatabasePathResolver.applicationPath); 

     } 
     return instance; 
    } 

    public String getApplicationPath() { 
     return applicationPath; 
    } 



     public String getUrlDatabase(String urlDatabase) { 


     return HsqlDatabasePathResolver.replaceAll(urlDatabase,"{apppath}", applicationPath); 
    } 


     /** 

     * 
     * replace the "\" character by "/" and remove relative paths 
     * 
     * @param path 
     * @return 
     */ 
     public static String normalizePath(String path) { 
      if (path == null) { 
       return null; 
      } 
      String normalized = path; 
      if (normalized.equals("/.")) { 
       return "/"; 
      } 
      if (normalized.indexOf('\\') >= 0) { 
       normalized = normalized.replace('\\', '/'); 
      } 
      if (!normalized.startsWith("/") && normalized.indexOf(':') < 0) { 
       normalized = "/" + normalized; 
      } 
      do { 
       int index = normalized.indexOf("//"); 
       if (index < 0) { 
        break; 
       } 
       normalized = normalized.substring(0, index) + normalized.substring(index + 1); 
      } while (true); 
      do { 
       int index = normalized.indexOf("/./"); 
       if (index < 0) { 
        break; 
       } 
       normalized = normalized.substring(0, index) + normalized.substring(index + 2); 
      } while (true); 
      do { 
       int index = normalized.indexOf("/../"); 
       if (index >= 0) { 
        if (index == 0) { 
         return null; 
        } 
        int index2 = normalized.lastIndexOf('/', index - 1); 
        normalized = normalized.substring(0, index2) + normalized.substring(index + 3); 
       } else { 
        return normalized; 
       } 
      } while (true); 
     } 




     public static String replaceAll(String str, String match, String replace) { 
      if (match == null || match.length() == 0) { 
       return str; 
      } 
      if (replace == null) { 
       replace = ""; 
      } 
      if(match.equals(replace))return str; 
      StringBuffer ret=new StringBuffer(); 
      int i = str.indexOf(match); 
      int y = 0; 
      while (i >= 0) 
      { 
       //System.out.println("i:"+i+" y:"+y); 
       ret.append(str.substring(y, i)); 
       ret.append(replace); 
       //str = str.substring(y, i) + replace + str.substring(i + match.length()); 
       y = i + match.length(); 
       i = str.indexOf(match,y); 
      } 
      ret.append(str.substring(y)); 
      return ret.toString(); 
     } 



} 

Et cette configuration que j'utilise au printemps:

<?xml version="1.0" encoding="UTF-8"?> 
    <beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-2.5.xsd 
       http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd"> 

    <!-- La definición del Datasource --> 
     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" lazy-init="true" 
     destroy-method="close"> 
      <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> 

      <property name="url"> 
       <ref bean="dataBaseUrl"/> 
      </property> 

      <property name="username" value="sa" /> 
      <property name="password" value="" /> 
     </bean> 

    <!-- La definición del Factory de Session con Anotaciones --> 
     <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="false"> 
      <property name="dataSource" ref="dataSource" /> 
      <property name="hibernateProperties"> 
       <props> 
        <prop key="hibernate.dialect"> 
     org.hibernate.dialect.HSQLDialect 
        </prop> 
        <prop key="hibernate.show_sql">true</prop> 
        <prop key="hibernate.format_sql">true</prop> 
       </props> 
      </property> 
      <property name="mappingResources"> 
       <list> 
        <value>Atoms.hbm.xml</value> 
       </list> 

      </property> 
     </bean> 
    <!--HibernaTemplate--> 
     <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> 
      <property name="sessionFactory"> 
       <ref bean="sessionFactory" /> 
      </property> 
     </bean> 
    <!-- Definición de los DAO`s --> 

     <bean id="ipBlancaDao" class="org.atoms.impl.AtomsDaoHibernateImpl"> 
      <property name="hibernateTemplate" ref="hibernateTemplate" /> 
     </bean> 


     <!--If your are not running in Web this will initialize with the directory from the process was started note that this classes is a singleton so if you are running in web the listener already have initialize the class with the path of the class--> 


     <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> 


    <bean id="hsqlDatabasePathResolver" class="com.atoms.HsqlDatabasePathResolver" factory-method="getInstance" lazy-init="false"> 
      <constructor-arg> 
       <value>${user.dir}</value> 
      </constructor-arg> 
     </bean> 

    <!--This bean just replace {apppath} whit the absolute path--> 

     <bean id="dataBaseUrl" class="java.lang.String" factory-bean="hsqlDatabasePathResolver" lazy-init="false" 
         factory-method="getUrlDatabase"> 
      <constructor-arg> 
       <value>jdbc:hsqldb:mem:{apppath}/WEB-INF/data/maf</value> 
      </constructor-arg> 

     </bean> 
    </beans> 

Et oui ce travail, mais est un bordel, je pense que la solution est l'auditeur, avec lui, vous pouvez obtenir le chemin de l'appWeb. Si quelqu'un peut rendre cela simple, s'il vous plaît poster la réponse.