如何在Grails 2.0上使MySQL运作?

17

Grails 2.0似乎对DataSource.groovy有一些更改,我似乎无法像1.3.7版本那样运行mysql。

我执行了grails install-dependency mysql:mysql-connector-java:5.1.16而不是仅仅将.jar文件放在lib中。我听说这是现在的做法。

以下是我在DataSource.groovy中替换的内容:

driverClassName = "org.h2.Driver"
...
url = "jdbc:h2:mem:devDb;MVCC=TRUE"

使用

driverClassName = "com.mysql.jdbc.Driver"
...
url = "jdbc:mysql://localhost:3306/${dbNamer}?autoreconnect=true"

将用户名、密码和数据库名称更改为有效的项...我做错了什么?是否有一份Grails 2.0教程涵盖设置mysql的内容?

我得到了这个庞然大物的错误:

| Loading Grails 2.0.0
| Configuring classpath.
| Environment set to development.....
| Packaging Grails application.....
| Compiling 1 source files.....
| Running Grails application
| Error 2012-01-16 21:39:10,134 [Thread-9] ERROR context.GrailsContextLoader  - Error     executing bootstraps: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Cannot resolve reference to bean 'hibernateProperties' while setting bean property 'hibernateProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateProperties': Cannot resolve reference to bean 'dialectDetector' while setting bean property 'properties' with key [hibernate.dialect]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dialectDetector': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
Message: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Cannot resolve reference to bean 'hibernateProperties' while setting bean property 'hibernateProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateProperties': Cannot resolve reference to bean 'dialectDetector' while setting bean property 'properties' with key [hibernate.dialect]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dialectDetector': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
    Line | Method
->>  334 | innerRun  in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    166 | run       in java.util.concurrent.FutureTask
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    679 | run . . . in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'transactionManager':     Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Cannot resolve reference to bean 'hibernateProperties' while setting bean property 'hibernateProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateProperties': Cannot resolve reference to bean 'dialectDetector' while setting bean property 'properties' with key [hibernate.dialect]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dialectDetector': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
->>  334 | innerRun  in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    166 | run       in java.util.concurrent.FutureTask
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    679 | run . . . in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'sessionFactory': Cannot resolve reference to bean 'hibernateProperties' while setting bean property 'hibernateProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateProperties': Cannot resolve reference to bean 'dialectDetector' while setting bean property 'properties' with key [hibernate.dialect]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dialectDetector': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
->>  334 | innerRun  in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    166 | run       in java.util.concurrent.FutureTask
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    679 | run . . . in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'hibernateProperties': Cannot resolve reference to bean 'dialectDetector' while setting bean property 'properties' with key [hibernate.dialect]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dialectDetector': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
->>  334 | innerRun  in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    166 | run       in java.util.concurrent.FutureTask
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    679 | run . . . in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'dialectDetector': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
->>  334 | innerRun  in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    166 | run       in java.util.concurrent.FutureTask
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    679 | run . . . in java.lang.Thread
Caused by MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
->>  334 | innerRun  in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    166 | run       in java.util.concurrent.FutureTask
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    679 | run . . . in java.lang.Thread
Caused by SQLNestedException: Cannot load JDBC driver class 'com.mysql.jdbc.Driver'
->> 1429 | createConnectionFactory in org.apache.commons.dbcp.BasicDataSource
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1371 | createDataSource in     ''
|   1044 | getConnection in     ''
|    334 | innerRun  in java.util.concurrent.FutureTask$Sync
|    166 | run . . . in java.util.concurrent.FutureTask
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    679 | run       in java.lang.Thread
Caused by ClassNotFoundException: com.mysql.jdbc.Driver
->>  217 | run       in java.net.URLClassLoader$1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    205 | findClass in java.net.URLClassLoader
|    321 | loadClass in java.lang.ClassLoader
|    266 | loadClass in     ''
|   1420 | createConnectionFactory in org.apache.commons.dbcp.BasicDataSource
|   1371 | createDataSource in     ''
|   1044 | getConnection in     ''
|    334 | innerRun  in java.util.concurrent.FutureTask$Sync
|    166 | run . . . in java.util.concurrent.FutureTask
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    679 | run       in java.lang.Thread
3个回答

21

install-dependency 只是下载 jar 包并将其放置在您的 Ivy 缓存中。但是您还没有声明您的应用程序依赖于该 jar 包。BuildConfig.groovy 中有一条注释掉的 MySQL 驱动程序依赖声明。只需取消注释并更新版本(如果需要),它就会将其添加到您的应用程序类路径中。如果您还没有使用 install-dependency 下载该 jar 包,则它也会将其下载到您的 Ivy 缓存中。


我是不是之前就忘了要做这件事,还是依赖关系在2.0中是新的?还是因为我使用了“install-dependency”而不是放置jar文件? - Mikey
2
它从1.2开始存在。就像我说的,“install-dependency”是一个全局的东西 - 它只是下载jar并缓存它,但对当前应用程序没有影响。请参见http://grails.org/doc/latest/ref/Command%20Line/install-dependency.html。 - Burt Beckwith

12

我刚才执行了grails>clean命令,它起作用了。


它对我也有效。命令类似于 app_name>grails clean。 - aman.nepid
是的,对我来说完全有效,不需要更改BuildConfig.groovy。 - moeTi
我在将jar文件直接放入“libs”而不是使用“install-dependency”时遇到了同样的问题。这对我起作用了。 - rhgb
然而,看起来“grails clean”对于从DataSource.groovy和BuildConfig.groovy编译的*.class文件没有影响。(我不知道这些文件是何时创建的。)但是手动使用groovyc删除和/或重新编译它们可以解决问题! - Sergey Orshanskiy

3

我最终编写了一段Groovy脚本来测试连接到MySQL的情况。下面是代码。将其放置在scripts/TestMysql.groovy中,并按照以下方式运行:

grails test test-mysql localhost 3306 test-db grails-user grails-password

首先,要进行的“测试”是在测试环境下运行脚本,以防DataSource.groovy有任何更改。

如果您可以使用此脚本连接到MySQL,那么您至少会知道DataSource.groovy的正确设置。如果成功,它还会打印与 DataSource.groovy 中要插入的相关 dataSource {} 部分。

/* Testing grails/GORM connection to mysql
 * Call this script "scripts/TestMysql.groovy"
 * Usage: "grails test-mysql" or, to run in another environment, e.g. "grails test test-mysql"
 * (This is in case you have changed DataSource.groovy and nothing is working.)
 *
 * Up to five parameters:
 * grails test test-mysql <host> <port> <database> <user> <password>
 * e.g. grails test test-mysql localhost 3306 test root rootpassword.
 * The database name can also be empty.
 */

import groovy.sql.Sql

includeTargets << grailsScript("_GrailsInit") << grailsScript("_GrailsArgParsing")

target(main: "The description of the script goes here!") {

    def list=argsMap['params']
    def host=list[0] ? list[0] : 'localhost'  
    def port=list[1] ? list[1] : '3306'       
    def db=list[2] ? list[2] : ''             // can leave empty
    def user=list[3] ? list[3] : 'grails'      
    def pswd=list[4] ? list[4] : 'grails'

    println "Connecting to " + host + ":" + port
    println "Database:" + db
    println "User: " + user
    println "Password: " + pswd

    def jdbc_string='jdbc:mysql://' + host + ':' + port + '/' + db

    def sql
    try {
        sql = Sql.newInstance(jdbc_string, user, pswd, "com.mysql.jdbc.Driver")
    } catch (com.mysql.jdbc.exceptions.jdbc4.CommunicationsException e) {
        println "ERROR! Cannot connect to " + host + ":" + port
        println "Check host, port, your open ports and other firewall settings; try to connect with some other program"
        println ""
        println e
        return
    } catch (com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException e) {
        println "MySQL ERROR, perhaps wrong database name!"
        println ""
        println e
        return
    } catch (java.sql.SQLException e) {
        println "MySQL ERROR, perhaps wrong login/password!"
        println ""
        println e
        return
    }

    println "SUCCESS! Connected to MySQL"
    def query = "SHOW DATABASES"

    println "Executing query " + query + "..."
    sql.eachRow(query) {
      println it
    }

    println "OK, Done!"

    println """
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:mysql://${host}:${port}/${db}"
            username="${user}"
            password="${pswd}"
        }
        """

}

setDefaultTarget(main)
更新:确实,一旦这个脚本工作了,那么使Grails也工作起来就很容易了。我只需要执行grails clean,删除所有幸存的*.class文件,恢复原始的DataSource.groovy,然后执行grails compile --refresh-dependencies。然后更改DataSource.groovy,就可以完美运行了。
下面是我的工作中的DataSource.groovy代码:
dataSource {
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    username = "sa"
    password = ""
}
hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:mysql://localhost:8890/test"
            username="grails"
            password="grails"
        }
    }
    test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
        }
    }
    production {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
            pooled = true
            properties {
               maxActive = -1
               minEvictableIdleTimeMillis=1800000
               timeBetweenEvictionRunsMillis=1800000
               numTestsPerEvictionRun=3
               testOnBorrow=true
               testWhileIdle=true
               testOnReturn=true
               validationQuery="SELECT 1"
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接