No SQL connection - spring

Recently I've decided to move from Common DBCP to Tomcat JDBC Connection Pool. I changed bean description (using spring 3.1 + hibernate 4 + tomcat) and was faced with the next issue on my web app start up:
HHH000342: Could not obtain connection to query metadata : com.mysql.jdbc.Driver
and then when I try to query db from my app I am getting:
23:04:40,021 WARN [http-bio-8080-exec-10] spi.SqlExceptionHelper:(SqlExceptionHelper.java:143) - SQL Error: 0, SQLState: null
23:04:40,022 ERROR [http-bio-8080-exec-10] spi.SqlExceptionHelper:(SqlExceptionHelper.java:144) - com.mysql.jdbc.Driver
I must have done something wrong with configuration so hibernate cannot obtain connection but do not see it. really appreciate if you can point me to the right direction.
here is piece of my datasource bean definition
<bean id="jdbcDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy- method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://127.0.0.1:3306/test"
p:username="root"
p:password="test"
p:defaultAutoCommit="false"
p:maxActive="100"
p:maxIdle="100"
p:minIdle="10"
p:initialSize="10"
p:maxWait="30000"
p:testWhileIdle="true"
p:validationInterval="60000"
p:validationQuery="SELECT 1"
p:timeBetweenEvictionRunsMillis="60000"
p:minEvictableIdleTimeMillis="600000"
p:maxAge="360000"
/>
and here is how I tie it with spring's session factory
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="jdbcDataSource" />...

Make sure you are using JDK 6. Using JDK5 might be one cause of this error.
However, there is a workaround to your problem, explained here.

after migration, I forgot to add lib tomcat-jdbc to my classpath :)
now it wroks

Related

Grails database configuration

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?
What do I need to do to run locally with my local MySql database?
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.
How do I get rid of "MYSQL" in myapp-PROD.xml and get dialect from
context.xml instead?
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.

Failing to connect to database some times spring-jdbc, commons-dbcp,tomcat

I am using spring3 and org.apache.commons.dbcp.BasicDataSource and apache tomcat 6.x.
Once the application is started it works fine but after some time it fails to connect to database... on restart it connects again.
below is configuration used in applicationContect.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:initialSize="5" p:maxActive="15" p:maxIdle="5" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://<Host>/<schema>?useUnicode=true&" p:username="<uName>" p:password="<pwd>" p:testOnBorrow="true" p:validationQuery="SELECT 1"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
Can there be any problem with the configuration?
Also, i am not closing/handling jdbc connections/resultset and i assume spring-jdbc will take care of it .
I am getting the below exception:
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, general error
executing stored procedures with jdbcTemplate.query was failing some times.
Instead i used org.springframework.jdbc.core.simple.SimpleJdbcCall for calling stored procedures and its working fine

BoneCP sometimes cannot get config from spring property holder

I have been facing this issue for a while now. My config is as following
<!-- Load Properties Files -->
<context:property-placeholder location="classpath:*-${environment}.properties" ignore-unresolvable="true"/>
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="idleConnectionTestPeriodInMinutes" value="${boneCP.idleConnectionTestPeriodInMinutes}"/>
<property name="idleMaxAgeInMinutes" value="${boneCP.idleMaxAgeInMinutes}"/>
<property name="maxConnectionsPerPartition" value="${boneCP.maxConnectionsPerPartition}"/>
<property name="minConnectionsPerPartition" value="${boneCP.minConnectionsPerPartition}"/>
<property name="partitionCount" value="${boneCP.partitionCount}"/>
<property name="acquireIncrement" value="${boneCP.acquireIncrement}"/>
<property name="statementsCacheSize" value="${boneCP.statementsCacheSize}"/>
<property name="lazyInit" value="true"/>
<property name="maxConnectionAgeInSeconds" value="${boneCP.maxConnectionAgeInSeconds}"/>
</bean>
The project is running on Tomcat 7
On the local machine, the project deploy with no error as well as for the dev server. Unfortunately, the project cannot be deployed on dev server any more (server configuration remain same) while local machine is still fine. Every time I deploy the project on the dev server, Tomcat just hang at INFO: Deploying web application archive /etc/tomcat/webapps/project.war. But if I config BoneCP with real values, everything is fine.
Could any one tell me what's wrong with it?
It turned out to be the lazyInit problem. If I comment it out, the server can start normally. But now I'm facing the new issue though. Mybatis cannot access the db at all while the local machine is 100% fine. and yet dont throw any exception. But when I stop the server, I found the following exceptions
INFO: Illegal access: this web application instance has been stopped already. Could not load com.jolbox.bonecp.PoolUtil. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1600)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
at com.jolbox.bonecp.DefaultConnectionStrategy.getConnectionInternal(DefaultConnectionStrategy.java:94)
at com.jolbox.bonecp.AbstractConnectionStrategy.getConnection(AbstractConnectionStrategy.java:90)
at com.jolbox.bonecp.BoneCP.getConnection(BoneCP.java:540)
at com.jolbox.bonecp.BoneCPDataSource.getConnection(BoneCPDataSource.java:131)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80)
at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:66)
AND
INFO: Illegal access: this web application instance has been stopped already. Could not load org.apache.ibatis.reflection.ExceptionUtil. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1600)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:363)
at sun.proxy.$Proxy15.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:195)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:124)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:90)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:40)
at sun.proxy.$Proxy45.selectByExample(Unknown Source)
Well it could be many things but its most likely
properties are not being replaced with the values you think
the database number of connections has been exceeded or the wrong host
A combination of 1 + 2
For #1 I would a make a separate bean that needs com.jolbox.bonecp.BoneCPDataSource as a dependency and have it print out the getters of BoneCPDataSource.
For #2 I would turn on as much logging as possible (see log4j or logback or whatever your logging framework is).

Spring tx:annotation-driven works in eclipse, but not in tomcat

I seem to have a problem with spring annotation-driven transaction managing and tomcat.
These are some of the beans I use in my project:
<bean id="dataSource" class="service.myBatis.RoutingDataSource"> </bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
Everything works fine when i run the project in eclipse. But when i run the project in tomcat it doens't get past the creation of beans. It also does not give me an error or any indication of what is wrong.
The log shows it finishes with instantiating a bean and then it suddenly destroys all beans:
[DEBUG] 12 jul 09:28:55.888 AM localhost-startStop-1 [org.springframework.beans.factory.support.DefaultListableBeanFactory]
Finished creating instance of bean 'org.springframework.transaction.config.internalTransactionAdvisor'
[INFO] 12 jul 09:28:55.895 AM localhost-startStop-1 [org.springframework.beans.factory.support.DefaultListableBeanFactory]
Destroying singletons in........
If i remove the <tx:annotation-driven transaction-manager="transactionManager" /> line the project will just startup normaly in tomcat and eclipse.
Usually if something works in eclipse and it doesn't in tomcat it is caused by tomcat not finding some class/lib or resource. I have no idea what is causing this though
Could anyone tell me what the problem is? Why does it destroy all the beans without giving an error?
I figured it out. It was not spring that was causing the problems it was something else in my project. The error was put in some tomcat log instead of to the console. So it seemed like there was no error.

Class load error on Spring MVC project for Spring newbie

Warning: newbie alert!
I'm in early days of learning Spring and am trying to get my first app up and running which will simply read some data from a DB and display it.
I'm using SpringSource Tool Suite 2.8.0.RELEASE. I've created a new Spring MVC project and want to read some data from a local MySQL DB.
I wrote a simple DAO class:
package com.blah.blah;
import org.springframework.jdbc.core.support.JdbcDaoSuppo rt;
public class MyDAO extends JdbcDaoSupport {
I've added this to the pom.xml file:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
I've added this to the root-context.xml (is this the right config file to update?):
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/dbname" />
<property name="username" value="root" />
<property name="password" value="mypw" />
</bean>
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate" >
<constructor-arg ref="myDataSource"></constructor-arg>
</bean>
<bean id="parentDAO"
class="org.springframework.jdbc.core.support.JdbcD aoSupport">
<property name="dataSource" ref="myDataSource"></property>
</bean>
When I right-click on the project and select Debug As > Debug On Server I get the error:
24-Mar-2012 16:13:42 org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of
class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.CannotLoadBeanClassException:
Cannot find class [org.springframework.jdbc.datasource.DriverManagerDataSource]
for bean with name 'myDataSource' defined in ServletContext resource
[/WEB-INF/spring/root-context.xml]; nested exception is
java.lang.ClassNotFoundException: org.springframework.jdbc.datasource.DriverManagerDataSource
I've been looking at this for a while and can't figure out what I'm doing wrong. I've found the folder where the app is deployed to (C:\Program Files\springsource\vfabric-tc-server-developer-2.6.1.RELEASE\spring-insight-instance\wtpwebapps\MyAppName\WEB-INF\lib on my machine) and the lib folder contains spring-jdbc-3.1.0.RELEASE.jar and when I open it, I can see the DriverManagerDataSource class file so I don't know why I'm getting the error above.
Any advice greatly appreciated.
Check that the Spring libraries are in the classpath so they are available for the server.
I had the same jar file included in the project twice. Removed one and it worked.
I had the same problem in Eclipse and creating a new workspace solved this problem.
I had added required jar source instead of release. Strange but changing that to release version fixed this problem.

Resources