Grails数据库配置
我正在尝试对Grails应用程序的数据库配置进行一些更改。 Grails版本为2.5.3。 目的是删除对MySQL的硬编码依赖关系,以便能够与其他数据库提供商一起使用该应用程序。 我还试图将环境设置为prod
以及本地MySQL数据库进行本地运行。 (为了能够在不部署的情况下测试我的更改,因为“开发”环境使用了设置完全不同的H2数据库。)因此,我从mvn Grails开始:run -app -dgrails.env = prod
。
我对圣杯的经验不太经验,似乎“神奇地”发生了很多事情,这使故障排除变得有些困难。
一些似乎涉及的配置文件是:
context.xml。据我了解,这是服务器上的tomcat配置文件(应用程序之外)。还有一个MyApp/Resources/tomcat-conf/context.xml,我相信当我在本地运行时使用它。 context.xml包含类似的数据库配置:
<Context>
...
<Resource name="jdbc/TP" auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="5" maxWait="10000" username="xxx" password="xxx"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://xxx:3306/xxx?autoReconnect=true" validationQuery="select 1"
/>
...
</Context>
然后,我想摆脱这里的MyApp/src/main/resource/myapp-prod.xml,
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="database" value="MYSQL" />
</bean>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/TP"/>
<property name="resourceRef" value="true" />
</bean>
我想摆脱这里的硬编码“ mysql”,并且可以从上下文中获得。 XML(或服务器上的属性文件)。
MyApp-prod.xml还导入MyApp-config.xml,其中包含:
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
然后在myApp/grails-app/conf/datasource.groovy中有一些配置: (包括一些量如何的配置)
environments {
...
production {
dataSource {
// driverClassName = "com.mysql.jdbc.Driver"
// username = "xxx"
// password = "xxx"
// url = "jdbc:mysql://xxx:3306/xxx"
jndiName = "java:comp/env/jdbc/TP"
}
}
}
,还有MyApp/Grails-App/Conf/Bootstrap.groovy,可以为“ dev”和“ test”进行一些H2配置,但没有对“ prod”的数据库配置。
因此,我尝试在context.xml中指定我的本地mySQL数据库。它不好用。在MyApp/target/tomcat/logs/myApp.log中,我可以看到:
*2022-05-23 13:40:01,669 [localhost-startStop-1] DEBUG spring.OptimizedAutowireCapableBeanFactory - Invoking afterPropertiesSet() on bean with name 'dialectDetector'
2022-05-23 13:40:05,703 [localhost-startStop-1] WARN spring.GrailsWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: 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 create PoolableConnectionFactory (**Could not create connection to database server. Attempted reconnect 3 times. Giving up.**)*
我在数据库日志中没有看到任何连接尝试,因此显然它并没有试图连接到context.xml中指定的数据库。 我还尝试在datasource.groovy中指定数据库,但这也不起作用。
因此:
- 与本地MySQL数据库本地运行我需要做什么?
- 我可以启用其他有用的日志吗?
- 如何在myApp-prod.xml中摆脱“ mysql”,而是从context.xml获得方言?
I'm trying to make some changes to the database configuration for a Grails application. Grails version is 2.5.3.
The goal is to remove hard coded dependencies to MySql to be able to use the application with other database providers.
I am also trying to run locally with environment set to prod
and with a local MySql database. (To be able to test my changes without deploying, since the "dev" environment uses the H2 database which is set up quite different.) So I'm starting with mvn grails:run-app -Dgrails.env=prod
.
I'm not very experienced with Grails and a lot of things seems to happen "magically" which makes troubleshooting a little difficult.
Some configuration files that seems to be involved are:
context.xml. As I understand it this is a tomcat configuration file on the server (outside the application). There is also a myapp/resources/tomcat-conf/context.xml which I believe is used when I'm running locally. context.xml contains a database configuration like this:
<Context>
...
<Resource name="jdbc/TP" auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="5" maxWait="10000" username="xxx" password="xxx"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://xxx:3306/xxx?autoReconnect=true" validationQuery="select 1"
/>
...
</Context>
Then there is a myapp/src/main/resources/myapp-PROD.xml
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
<property name="database" value="MYSQL" />
</bean>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/TP"/>
<property name="resourceRef" value="true" />
</bean>
I would like to get rid of the hardcoded "MYSQL" here and preferable be able to get that from context.xml (or a properties file on the server).
myapp-PROD.xml also imports myapp-config.xml which contains:
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
Then there is some configuration in myapp/grails-app/conf/DataSource.groovy:
(Including some outcommented configuration)
environments {
...
production {
dataSource {
// driverClassName = "com.mysql.jdbc.Driver"
// username = "xxx"
// password = "xxx"
// url = "jdbc:mysql://xxx:3306/xxx"
jndiName = "java:comp/env/jdbc/TP"
}
}
}
And there is also myapp/grails-app/conf/BootStrap.groovy which does some H2 configuration for "dev" and "test" but no database configuration for "prod".
So I have tried to specify my local MySql database in context.xml. It does not work well. In myapp/target/tomcat/logs/myapp.log I can see this:
*2022-05-23 13:40:01,669 [localhost-startStop-1] DEBUG spring.OptimizedAutowireCapableBeanFactory - Invoking afterPropertiesSet() on bean with name 'dialectDetector'
2022-05-23 13:40:05,703 [localhost-startStop-1] WARN spring.GrailsWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: 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 create PoolableConnectionFactory (**Could not create connection to database server. Attempted reconnect 3 times. Giving up.**)*
I don't see any connection attempts in my database logs, so obviously it is not trying to connect to the database i specified in context.xml.
I also tried to specify the database in DataSource.groovy, but that didn't work either.
So:
- What do I need to do to run locally with my local MySql database?
- Is there any additional helpful logs I can enable?
- How do I get rid of "MYSQL" in myapp-PROD.xml and get dialect from context.xml instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要为指向MySQL驱动程序的DataSource驱动程序提供一个值,并且需要提供MySQL驱动程序识别并指向您本地MySQL的JDBC URL。
方言只是难题的1个,可能确实不是问题的关键。如果确实需要从
context.xml
获得方言,我不知道该怎么做,但是处理情况的更常见的方法是使用JNDI必须在应用程序中提及方言,驱动程序名称以及用户名和密码。另一个选项是将数据库配置放入应用程序在启动时加载的外部配置文件中。You need to supply a value for the dataSource driver that points to the Mysql driver and you need to supply a JDBC url that the MySql driver recognizes and points to your local MySql.
The dialect is only 1 piece of the puzzle and probably really isn't the key to the problem. If it really is a requirement to get the dialect from
context.xml
I don't know how to do it, but a much more common way to deal with the situation is to either use JNDI so you don't have to make any mention of dialects and driver names and user names and passwords in your app. Another option is to put the database config in an external config file that is loaded by the app at startup time.