views:

10140

answers:

11

I'm trying to unit test (JUnit) a DAO i've created. I'm using Spring as my framework, my dao (JdbcPackageDAO) extends SimpleJdbcDaoSupport. The testing class (JdbcPackageDAOTest) extends AbstractTransactionalDataSourceSpringContextTests. I've overriden the configLocations as follows:

protected String[] getConfigLocations(){
 return new String[] {"classpath:company/dc/test-context.xml"};
}

My test-context.xml file is defined as follows:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&gt;

    <bean id="dataPackageDao" class="company.data.dao.JdbcPackageDAO">
     <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
     <property name="url" value="jdbc:hsqldb:hsql://localhost"/>
     <property name="username" value="sa" />
     <property name="password" value="" />
    </bean>

    <bean id="propertyConfigurer" 
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>company/data/dao/jdbc.properties</value>
            </list>
        </property>
    </bean>

    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
</beans>

I'm using HSQL as my backend, it's running in standalone mode. My IDE of choice is eclipse. When I run the class as a Junit test here's my error (below). I have no clue as to why its happening. hsql.jar is on my build path according to eclipse.

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: No suitable driver found for jdbc:hsqldb:hsql://localhost
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:219)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:377)
    at org.springframework.test.AbstractTransactionalSpringContextTests.startNewTransaction(AbstractTransactionalSpringContextTests.java:387)
    at org.springframework.test.AbstractTransactionalSpringContextTests.onSetUp(AbstractTransactionalSpringContextTests.java:217)
    at org.springframework.test.AbstractSingleSpringContextTests.setUp(AbstractSingleSpringContextTests.java:101)
    at junit.framework.TestCase.runBare(TestCase.java:128)
    at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:76)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:120)
    at junit.framework.TestSuite.runTest(TestSuite.java:230)
    at junit.framework.TestSuite.run(TestSuite.java:225)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.SQLException: No suitable driver found for jdbc:hsqldb:hsql://localhost
    at java.sql.DriverManager.getConnection(Unknown Source)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:291)
    at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:277)
    at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:259)
    at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:241)
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:182)
    ... 18 more
A: 

It looks like you're not specifying a database name to connect to, should go something like

jdbc:hsqldb:hsql://serverName:port/DBname
Max Stewart
A: 

Can you import the driver (org.hsqldb.jdbcDriver) into one of your source files? (To test that the class is actually on your class path).

If you can't import it then you could try including hsqldb.jar in your build path.

Max Stewart
I am able to import jdbcDriver; which means hsqldb is on my build path.
oneBelizean
A: 

It might be that

hsql://localhost

can't be resolved to a file. Look at the sample program here:

Sample HSQLDB program

See if you can get that working first, and then see if you can take that configuration information and use it in the Spring bean configuration.

Good luck!

MetroidFan2002
A: 

I think your HSQL URL is wrong. It should also include the database name,

so something like

jdbc:hsqldb:hsql://localhost/mydatabase

if mydatabase is the name of your DB (file). Not including this can (I'm not sure if it is the case here) confuse the parsing of the URL, which may lead to the DriverManagerDS thinking that your driver is not suitable (it is found, but it thinks it is not a good one)

NR
+2  A: 

Okay so here's the solution. Most everyone made really good points but none solved the problem (THANKS for the help). Here is the solution I found to work.

  1. Move jars from .../web-inf/lib to PROJECT_ROOT/lib
  2. Alter build path in eclipse to reflect this change.
  3. cleaned and rebuilt my project.
  4. ran the junit test and BOOM it worked!

My guess is that it had something to do with how Ganymede reads jars in the /web-inf/lib folder. But who knows... It works now.

oneBelizean
A: 

Not sure if it's worth anything, but I had a similar problem where I was getting a "java.sql.SQLException: No suitable driver found" error. I found this thread while researching a solution.

The way I ended up solving my problem was to forgo using java.sql.DriverManager to get a connection and instead built up an instance of org.hsqldb.jdbc.jdbcDataSource and used that.

The root cause of my problem (I believe) had to do with the classloader hierarchy and the fact that the JRE was running Java 5. Even though I could successfully load the jdbcDriver class, the classloader behind java.sql.DriverManager was higher up, to the point that it couldn't see the hsqldb.jar I needed.

Anyway, just putting this note here in case someone else stumbles by with a similar problem.

A: 

"no suitable driver" usually means that the syntax for the connection URL is incorrect.

duffymo
+1  A: 

If you look at your original connection string:

<property name="url" value="jdbc:hsqldb:hsql://localhost"/>

The Hypersonic docs suggest that you're missing an alias after localhost:

http://hsqldb.org/doc/guide/ch04.html

duffymo
A: 

I had the same problem with spring, commons-dbcp and oracle 10g. Using this URL I got the 'no suitable driver' error: jdbc:oracle:[email protected]:1521:kinangop

The above URL is missing a full colon just before the @. After correcting that, the error disappeared.

I also found out that org.springframework.jdbc.datasource.DriverManagerDataSource gives a more informative error for the same condition.
A: 

Agree, "not suitable driver found" in my case was because of an incorrect URL. Thanks J.A.

Joe Smith
+1  A: 

In order to have HSQLDB register itself, you need to access its jdbcDriver class. You can do this the same way as in this example.

Class.forName("org.hsqldb.jdbcDriver");

It triggers static initialization of jdbcDriver class, which is:

static {
    try {
        DriverManager.registerDriver(new jdbcDriver());
    } catch (Exception e) {}
}
Ivan
He already fixed the problem.
BalusC
I saw that, but I had the similar problem and the solution to it was as shown above. So I thought why not share it with my fellow overflowers ;)
Ivan