20

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 overridden 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">

    <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
Jim Ferrans
  • 30,582
  • 12
  • 56
  • 83
IaCoder
  • 12,300
  • 11
  • 37
  • 45

15 Answers15

30

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) {}
}
shark8me
  • 638
  • 8
  • 9
Ivan Koblik
  • 4,285
  • 1
  • 30
  • 33
  • 7
    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 Koblik Feb 15 '10 at 09:39
  • as a note, with jdbc4 it should "auto register" drivers so you shouldn't need any Class.forName or registerDriver calls anymore, FWIW – rogerdpack Aug 20 '14 at 20:17
11

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

duffymo
  • 305,152
  • 44
  • 369
  • 561
4

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.

IaCoder
  • 12,300
  • 11
  • 37
  • 45
3

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
  • 305,152
  • 44
  • 369
  • 561
2

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
  • 3,573
  • 26
  • 28
2

great I had the similar problem. The advice for all is to check jdbc url sintax

gianluca
  • 21
  • 1
1

As some answered before, this line of code solved the problem

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

But my app is running in some tomcats but only in one installation I had to add this code.

Thiem Nguyen
  • 6,345
  • 7
  • 30
  • 50
Emac
  • 29
  • 2
1

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
  • 3,573
  • 26
  • 28
1

I had the same problem with spring, commons-dbcp and oracle 10g. Using this URL I got the 'no suitable driver' error: jdbc:oracle:thin@192.168.170.117: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. –  Jan 09 '09 at 13:03
1

when try to run datasource connectivity using static main method, first we need to run database connection. This we can achieve in eclipse as bellow.

1) open any IDE(Eclipse or RAD) after opening workspace by default IDE will be opened in JAVA prospective. Try to switch from java to database prospective in order to create datasource as well as virtual database connectivity.

2)in database prospective enter all the details like userName, Password and URL of the particular schema.

3)then try to run main method to access database.

This will resolve the "serverName undefined".

Dan
  • 10,531
  • 2
  • 36
  • 55
0

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
  • 29,217
  • 16
  • 62
  • 80
0

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.
  • 402
  • 5
  • 6
0

I was facing similar problem and to my surprise the problem was in the version of Java. java.sql.DriverManager comes from rt.jar was unable to load my driver "COM.ibm.db2.jdbc.app.DB2Driver".

I upgraded from jdk 5 and jdk 6 and it worked.

poonam
  • 11
  • 2
0

In some cases check permissions (ownership).

CamelTM
  • 1,225
  • 12
  • 17
0

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.