tgr
tgr

Reputation: 3608

Cannot connect multiple times to mysql

I am writing an own databse in scala. To verify my results are correct, I check with a MySQL inside of a specs2 specification. I get the right result and everything is just fine. But if I run the test again without any changes, I get a SQLException: No suitable driver found for jdbc:mysql://localhost:3306/DBNAME?user=DBUSER (null:-1). Why is the driver not loaded again?

Edit

import java.sql.{ Connection, DriverManager, ResultSet }
import org.specs2.mutable.Specification
// SDDB imports ...

class DBValidationSpec extends Specification {

  "SDDB and MySQl" should {
    // SDDB
    // ...
    // JDBC
    val connectionString = "jdbc:mysql://localhost:3306/sddb_test?user=root"
    val query = """SELECT content, SUM( duration ) duration
                    FROM test
                    WHERE times
                    BETWEEN  '2011-12-08'
                    AND  '2011-12-09'
                    GROUP BY content"""
    classOf[com.mysql.jdbc.Driver]

    "give the same result" in {
      // ...
      //sddbResult

      lazy val conn = DriverManager.getConnection(connectionString)
      try{
        val rs = conn.createStatement().executeQuery(query)
        var mysqlResult = Map[List[String], Int]()
        while (rs.next) {
          mysqlResult += (rs.getString("content") :: Nil) -> rs.getInt("duration")
        }
        sddbResult == mysqlResult && sddbResult.size == 478 must beTrue 
      } finally {
        conn.close()
      }
    }

  }

}

I left out some parts of my code because they don't belong to the question.

Edit #2

The problem became even weirder. I added a second testcase. The testcase uses the same connectionString. The Exception was only raised once. The second test succeeded. I added sequential to my test definition and saw that only the first executed test raises the Exception. Afterwards I traced the classLoader to check if it is the same one. It is.
I did the following workaround:

trait PreExecuting extends Before {
  override def before {
    var conn: Option[Connection] = None
    try {
      val connectionString = "jdbc:mysql://localhost:3306/sddb_test?user=root"
      conn = Some(DriverManager.getConnection(connectionString))
    } catch {
      case _ =>
    } finally {
      conn map (_.close())
    }
  }
}

I don't get the Exception any more because I suppress it by using the PreExecution tait. But I still wonder what is going wrong here.

Upvotes: 2

Views: 323

Answers (3)

Daniel Espinosa
Daniel Espinosa

Reputation: 11

It's seems to be a problem with the Driver registration, the Driver has to be registered some like this...

DriverManager.registerDriver(new com.mysql.jdbc.Driver());   
or some like this...
DriverManager.registerDriver(new DriverWrapper((Driver) Class.forName(props.getProperty("dbg.driver"), true, gcloader).newInstance()));

before use getConnection. I hope this help.

Upvotes: 1

Joop Eggen
Joop Eggen

Reputation: 109547

I cannot pin down the error, to the following, but at least better also close the result set and statement.

    val stmt = conn.createStatement()
    val rs = stmt.executeQuery(query)
    var mysqlResult = Map[List[String], Int]()
    while (rs.next) {
      mysqlResult += (rs.getString("content") :: Nil) -> rs.getInt("duration")
    }
    sddbResult == mysqlResult && sddbResult.size == 478 must beTrue 
    rs.close()
    stmt.close()

Upvotes: 1

duffymo
duffymo

Reputation: 308763

The driver is only loaded once.

No suitable driver usually means that the connection URL syntax is incorrect.

Upvotes: 0

Related Questions