getting java.io.EOFException when trying to insert data in mysql from spring mvc app - mysql

I am trying to submit data from spring mvc app to mysql . sometime i get the following error
org.springframework.dao.DataAccessResourceFailureException: StatementCallback; SQL [insert into networkwithusdb(company,firstname,lastname,email,address1,address2,city,state,zipcode,currentemployer,currentjobtitle,primarycareerarea,secondarycareerarea) values('HCA North Texas','dd','af','bhanukiran#imomentous.info','','','','KS','','','','Facilities','Facilities')]; Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.io.EOFException
STACKTRACE:
java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1963)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2375)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2874)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3243)
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1343)
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1260)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:508)
at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:1)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:395)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:518)
at com.imomentous.hcanorthtexas.service.DatabaseService.insertNetworkData(DatabaseService.java:58)
at com.imomentous.hcanorthtexas.controller.NetworkWithUsController.processNetworkWithUSForm(NetworkWithUsController.java:62)
[... snip ...]
** END NESTED EXCEPTION **
only few times i get this exception.
following are my configuration file:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>${database.driver}</value>
</property>
<property name="url">
<value>${database.url}</value>
</property>
<property name="username">
<value>${database.username}</value>
</property>
<property name="password">
<value>${database.password}</value>
</property>
<property name="maxActive" value="5" />
<property name="initialSize" value="3" />
<property name="validationQuery" value="SELECT 5 FROM DUAL" />
<property name="testOnBorrow" value="true" />
</bean>
and i am using the properties as:
database.driver =com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/XXXmobiledb
database.username=XXXX
database.password=XXXX
i am using:mysql-connector-java-5.0.5.jar
mysql server 5 .
sometimes database connection works properly and i get the result.
but sometimes it generates the error.
what might be the problem? If any have some idea please tell..thanks

The fact is that MySQL will disconnect the opened socket after a given time. You are advised to use a connection pool (such as c3p0).
See this post on the MySQL forum - http://forums.mysql.com/read.php?39,143312,180718#msg-180718. This should resolve it for you.

It might happen after a long time of inactivity add validation Query to your dataSource bean:
<property name="validationQuery">
<value>Select 1</value>
</property>

To avoid MySQL from disconnecting your session after a given idle time, you can use Spring OpenSessionInViewFilter or Interceptor to handle session.
This will require additional session filter settings in your web.xml file. You can mimic this post.

Related

Spring MVC & Hibernate stops working after 8 hours

The following xml config file stops working after 8 hours of inactivity with this Error:
ERROR: Already closed.
25-may-2017 8:45:23 org.apache.catalina.core.StandardWrapperValve invoke
Servlet.service() for servlet [dispatcher] in the context with path [/system] threw exception [Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.TransactionException: JDBC begin transaction failed: ] with root cause:
java.net.SocketException: **Software caused connection abort: recv failed**
Below is the Configuration file:
<context:component-scan base-package="es.company.system.persistence" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="es.mypackage.model"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="connection.url" value="jdbc:mysql://localhost:3306/system" />
<property name="connection.username" value="???" />
<property name="connection.password" value="???" />
<property name="hibernate.c3p0.min_size" value="5" />
<property name="hibernate.c3p0.max_size" value="20" />
<property name="hibernate.c3p0.timeout" value="1800"/>
<property name="hibernate.c3p0.max_statements" value="50" />
<property name="hibernate.c3p0.testConnectionOnCheckout" value="true" />
<property name="hibernate.c3p0.privilegeSpawnedThreads" value="true" />
<property name="hibernate.c3p0.contextClassLoaderSource" value="library" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<tx:annotation-driven transaction-manager="transactionManager" />
I'm currently using Spring MVC 4.3.8 and Hibernate 4.1.9. with C3P0 conections pool for MySQL. I thought with C3P0 this would be solved, but it's not.
Anyone knows what's wrong?
Thanks!!!
Software caused connection abort: recv failed --
This usually means that there was a network error, such as a TCP timeout.
also set timeout param with default = 0 for hibernate.c3p0.timeout
hibernate.c3p0.timeout – When an idle connection is removed from the
pool (in second). Hibernate default: 0, never expire.
set autoReconnect , hibernate.c3p0.autoReconnect = true or as url connection param : jdbc:mysql://localhost:3306/test?autoReconnect=true
Add < property name="hibernate.c3p0.preferredTestQuery">SELECT 1</property>
and check it log that c3p0 execute it(if not add real select count(1) from real table with limit 1). Also check your network timeout
I have experienced this issues some time google cloud sql where the SQL server breaks all the connection after idle time out of 10 hrs. But in the application we still have the sessionFactory instance and can create sessions but when you actually fire a db query it fails with broken connection exception.
None of the below attempts worked.
1. auto reconnect set in connection url
2. auto reconnect, timeout, validation properties in xml file.
3. Wrote a polling service to make a jdbc call to keep the connection active for every 8 hrs (<10 hrs idle time out period)
4. Closed and opened new sessionFactory for every db operation.
Finally i have created a polling service which will shutdown the sessiongFactory and create a new one.
NOTE: Calling close method on sessionFactory object is not sufficient. You need to explicit set it to null;
This may be a workaround but it saved me from day restart of the application.
I was not using spring just rest service with hibernate.

Getting The application must supply JDBC connections exception

I am getting Application must provide JDBC connection exception while trying to perform query on Mysql DB using Spring+hibernate
Application context has following entry
<bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="appDataSource" />
</bean>
<bean id="appDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.mariadb.jdbc.Driver" />
<property name="url" value="jdbc:mariadb://localhost:3306/appdb" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
And JNDI name as
<jee:jndi-lookup id="appDataSource" jndi-name="java:comp/env/jdbc/Modeling"/>
Complete stack trace
java.lang.UnsupportedOperationException: The application must supply JDBC connections
at org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:44)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:386)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:84)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java: )
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:47)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1927)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1896)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1874)
at org.hibernate.loader.Loader.doQuery(Loader.java:919)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336)
at org.hibernate.loader.Loader.doList(Loader.java:2610)
at org.hibernate.loader.Loader.doList(Loader.java:2593)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2422)
at org.hibernate.loader.Loader.list(Loader.java:2417)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1339)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87)
at org.hibernate.internal.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:964)
Hibernate configuration
<hibernate-configuration>
<session-factory>
<mapping resource="service.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Service.hbm.xml file
<hibernate-mapping>
<class name="service.repository.Account"
table="ACCOUNTS" discriminator-value="null">
<id name="id" column="id" type="java.lang.Long">
//all other entry
</class>
</hibernate-mapping>
Do the below -
1)check hibernate.cgf.xml(or your hibernate config file) & confirm if below are correct -
hibernate.connection.url
hibernate.connection.username
hibernate.connection.password
hibernate.dialect
hibernate.connection.driver_class
2) Check for the datasource name you have define in your standalone.xml(JBoss config file).It should match with your jndi-name ="java:datasource_name"
I assume your "java:comp/env/jdbc/Modeling" JNDI name does not point to a valid data source object.
Issue is solved after removing Jrebel plugin from server settings.
Some how jrebel was messing with the configuration.
Upgraded rebel configuration and things are working fine now.
If not resolved yet them try giving path of hibernate.cfg.xml to configure object
cfg.configure("hibernate.cfg.xml");
and also can skip dialect property in xml if you are not able to select right one for yourself .
it worked for me.

Adding c3p0 to spring hibernate project

I had some trouble with connection timeouts. Problem: After mysql timeout hibernate stops working. It seams to work fine, but it does not write further data to database. After searching the logs, I found the hint: last connection 53000 seconds - connection problem. Timeout is mysql-default (28000). So I tried increasing mysql timeout, but won't use in production system.
Searching for a better solution, I found out, that probably c3p0 could solve my problem with a test query.
I am using hibernate with spring. That's were trouble starts. I added c3p0 as DataSource (Bean):
<bean id="dataSource_archiv" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${hibernate.connection.driver_class}" />
<property name="jdbcUrl" value="${hibernate.connection.url}" />
<property name="user" value="${hibernate.connection.username}" />
<property name="password" value="${hibernate.connection.password}" />
<property name="minPoolSize" value="${hibernate.connection.minPoolSize}" />
<property name="maxPoolSize" value="${hibernate.connection.maxPoolSize}" />
<property name="maxIdleTime" value="${hibernate.connection.maxIdleTime}" />
<property name="maxStatements" value="${hibernate.connection.maxStmts}" />
<property name="testConnectionOnCheckout" value="${hibernate.connection.testCo}" />
<property name="testConnectionOnCheckin" value="${hibernate.connection.testCo}" />
<property name="preferredTestQuery" value="${hibernate.connection.testSQL}" />
<property name="idleConnectionTestPeriod" value="${hibernate.connection.testPeriod}" />
</bean>
Complete hibernate Config File.
But afterwards, the application cannot be started anymore:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field
Complete Stack trace.
So probably I misconfigured something. Where can I start analyzing the problem?
Or is there any other good solution? Like starting a Native SQL from hibernate to keep connection alive? I would prefer the solution with c3p0.
Thanks.

java.sql.SQLException: Already closed

We have a webapp running in production on tomcat with a MySQL back-end. All was fine for sometime, then suddenly we started getting this exception java.sql.SQLException: Already closed.
The entire stack trace is:
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] Fetching JDBC Connection from DataSource
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] Returning JDBC Connection to DataSource
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] Could not close JDBC Connection
java.sql.SQLException: Already closed.
at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:114)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:191)
at org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:333)
at org.springframework.jdbc.datasource.DataSourceUtils.releaseConnection(DataSourceUtils.java:294)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:405)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:428)
at com.nokia.analytics.aws.aggregate.service.importer.DBInsert.truncateTable(DBInsert.java:135)
at com.blah.analytics.aggregate.service.importer.AggregateCollector.pullAndInsert(AggregateCollector.java:85)
at com.blah.analytics.aggregate.service.importer.AggregateCollector.call(AggregateCollector.java:96)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:679)
We are using org.apache.commons.dbcp.BasicDataSource as our datasource. I searched quite a bit but to no avail.
It doesn't occur always and hence is very hard to reproduce. It seems a problem with db connection pooling. Somewhere it was suggested to set this param as negative. Currently we are not changing of those parameters (all have default vals).
What approach should we follow to avoid it?
EDIT:
The relevant code is in (DBInsert.java)
133: String sql = "DELETE FROM "+tableName;
134: logger.debug(sql);
135: this.jdbcTemplate.execute(sql);
(133-135 are line nos. which are specified in the exception)
My datasource config:
<bean id="bisToolDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="${url}/blah_db?verifyServerCertificate=false&useSSL=true&requireSSL=true" />
<property name="username" value="${uname}" />
<property name="password" value="${passwd}" />
</bean>
The cause of this problem is connection isn't used in a long time, add testOnBorrow and validationQuery property to your datasource configuration then your application will work fine.
Good luck:)
As user NobodyElse pointed out, the problem was related to connection pooling. I was using org.apache.commons.dbcp.BasicDataSource as datasource. The nature of the application is such that there is spurt of connections at some fixed time in the day and no connections at all for the entire day. So due to this connections in the pool were getting stale and when next day application tried to connect to DB, we were getting this exception.
There are basically two solutions to this:
The one pointed out by NobodyElse, that is to use testOnBorrow; details can be found here
The other solution (which I employed for our app) is to turn off pooling completely. Note do this only when the application is not DB intensive (which was true in our case). So I switched to org.springframework.jdbc.datasource.DriverManagerDataSource. The config for which it seems to be working fine is:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="${url}/blah_db?verifyServerCertificate=false&useSSL=true&requireSSL=true" />
<property name="username" value="${uname}" />
<property name="password" value="${passwd}" />
</bean>

Setting noAccessToProcedureBodies using a DriverManagerDataSource bean

Hi all fellow Java Geeks,
I have lots of stored procedures in a MySQL database, which I can call successfully from .NET. However, when calling them from Java Spring SimpleJdbcCall.execute() I get an exception telling me that the user doesn't have the privilege to do so. But that is clearly not the case since the same user can access it both from CLI and .NET.
I would therefore like to set this parameter:
noAccessToProcedureBodies=true
However, when adding the parameter in my url in the connector bean below, it thinks that the trailing characters are a part of the database name.
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="username">
<value>user</value>
</property>
<property name="url">
<value>jdbc:mysql://192.168.0.1:3306/database/?noAccessToProcedureBodies=true</value>
</property>
<property name="password">
<value>powerpass</value>
</property>
</bean>
I have been looking at overriding the getConnectionProperties method, but I don't think that's the right approach?
Thanks all
I found an answer myself, and it's working.
Instead of having an ending slash "database/?noAccess..." one should leave it:
<property name="url">
<value>jdbc:mysql://192.168.0.1:3306/database?noAccessToProcedureBodies=true</value>
</property>
Hope that help someone!