Setting noAccessToProcedureBodies using a DriverManagerDataSource bean - mysql

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!

Related

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.

Why is Hibernate response not reflected when making direct changes in the database?

When I made direct changes in the database, it's not reflected in the webservices response on request, however it is working once I restart the server. How can I make changes work immediately?
My hibernate configuration file looks like this:
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/demo</property>
<property name="hibernate.connection.username">xxxx</property>
<property name="hibernate.connection.password">xxxx</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
</session-factory>
</hibernate-configuration>
This is because you have use_second_level_cache set to true.
Change the value of use_second_level_cache to false and would hit db every time without using 2nd level cache

About c3p0 and hibernate

I write a hibernate.cfg.xml file almost the same from hibernate books like:
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.connection.password">**</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/db</property>
<property name="hibernate.connection.username">**</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="c3p0.min_size">5</property>
<property name="c3p0.max_size">30</property>
<property name="c3p0.time_out">1800</property>
<property name="c3p0.max_statement">50</property>
<!--property name="show_sql">true</property-->
<property name="format_sql"> true</property>
But this seems actually c3p0 is not used. When I do test to establish 1000 sessions, it tries to establish 1000 connections.
Could anyone please give me some hint about this?
Thank you
Looking at your configuration file seems that you are missing one key property
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
Try setting this property and see if this turns things around for you or not.

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

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.

Hibernate, C3P0, Mysql -- Broken Pipe

MySQL seems to have an 8 hour time out on its connections. I'm running multiple WARs in Tomcat utilizing Hibernate for ORM. After 8 hours (i.e. overnight), I get broken pipes when it picks up an idle connection.
I've already traced through the code and made doubly sure I commit or rollback all transactions.
Here is my hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.current_session_context_class">thread</property>
<!--property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property-->
<property name="c3p0.min_size">3</property>
<property name="c3p0.max_size">5</property>
<property name="c3p0.timeout">1800</property>
<property name="c3p0.preferredTestQuery">SELECT 1</property>
<property name="c3p0.testConnectionOnCheckout">true</property>
<property name="c3p0.idle_test_period">100</property> <!-- seconds -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="cache.use_query_cache">false</property>
<property name="cache.use_minimal_puts">false</property>
<property name="max_fetch_depth">10</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- classes removed -->
</session-factory>
The parameter I thought would have fixed it was the c3p0.idle_test_period -- It defaults to 0. However, we still have the Broken Pipe issue after 8 hours of running. While there are multiple posts index via Google, none arrive at a satisfactory answer.
So it turns out I was missing a key line that enabled c3p0 (the c3p0 parameters I was tweaking were having no effect because Hibernate was using it's built in connection pool -- which it appropriately warns is not suitable for production). In hibernate 2.x, setting the hibernate.c3p0.max_size property enabled c3p0 connection pooling. However, in 3.x you must specify the following property --
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
Additionally, here are my final configuration parameters --
<property name="hibernate.c3p0.min_size">3</property>
<property name="hibernate.c3p0.max_size">5</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.idle_test_period">100</property> <!-- seconds -->
It's rather unfortunate that both Hibernate and c3p0 have abysmal documentation in this regard.
There are two things going on here. You should read this article for more details, but the take-aways are:
You can adjust the MySQL wait_timeout setting to something larger than 8 hours, if desired.
The Hibernate settings should include "hibernate." before the "c3p0", e.g. hibernate.c3p0.idle_test_period instead of just c3p0.idle_test_period
This is a solution when you have a broken pipe because of combination of tomcat's wait_timeout=28800 sec(8h) and maxIdleTime=0 in c3p0:
I've changed the local tomcat wait_timeout via my.ini file to 120sec (2 min). And I placed the following:
maxIdleTime=100
idleConnectionTestPeriod=0 (same as default/as if it didn't exist)
other:
acquireIncrement=2
minPoolSize=2
maxPoolSize=5
maxIdleTimeExcessConnections=10
I had no problems with this setup.
I didn't need to use idleConnectionTestPeriod!
If tomcat's wait_timeout is 28800 sec, and maxIdleTime is 25200, it means that c3p0 will close the idle connection in 3600sec (1h) earlier, before tomcat throws a "broken pipe" exception. Isn't that right?!
As you can see I have no issues with providing only maxIdleTime.
Unfortunately, these:
maxIdleTime
idleConnectionTestPeriod
configuring_connection_testing
testConnectionOnCheckin
don't explain too much the corner cases.
And, btw, here is how to open the tomcat's my.ini file with Notepad++:
http://drupal.org/node/32715#comment-4907440
Cheers,
Despot
I've several problem -
- C3P0ConnectionProvider was not found
- I solve it by using the hibernate c3p0 version
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.5.6-Final</version>
</dependency>
<!-- c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>3.3.1.GA</version>
</dependency>
- I have that wait_timeout issue on mysql. First I set /etc/my.cnf wait_timeout=10
then I changed the Idle time out value to lower than the wait_timeout value which < 10
That solved my problem.
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" /> <property name="hibernate.c3p0.acquire_increment" value="1" />
<property name="hibernate.c3p0.idle_test_period" value="28690"/>
<property name="hibernate.c3p0.timeout" value="1800" />
<property name="hibernate.c3p0.max_size" value="5" />
<property name="hibernate.c3p0.min_size" value="3" />
<property name="hibernate.c3p0.max_statement" value="50" />
<property name="hibernate.c3p0.preferredTestQuery" value="select 1;"/>
I was getting the same problem and it took time to figure out the solution.
I use Hibernate 4.0.1 and mysql 5.1(no spring framework) and I was facing the issue. First make sure that you configured the c3p0 jars properly which are essential.
I used these properties in hibernate.cfg.xml
<property name="hibernate.c3p0.validate">true</property>
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property>
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property>
<property name="hibernate.c3p0.idle_test_period">10</property>
<property name="hibernate.c3p0.acquireRetryAttempts">5</property>
<property name="hibernate.c3p0.acquireRetryDelay">200</property>
<property name="hibernate.c3p0.timeout">40</property>
But it's of no use 'cause C3p0 was still taking the default properties not the properties which I set in hibernate.cfg.xml, You can check it in logs. So, I searched many websites for right solution and finally I came up with this. remove the C3p0 properties in cfg.xml and create c3p0-config.xml in the root path(along with cfg.xml) and set properties as follows.
<c3p0-config>
<default-config>
<property name="automaticTestTable">con_test</property>
<property name="checkoutTimeout">40</property>
<property name="idleConnectionTestPeriod">10</property>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">20</property>
<property name="minPoolSize">5</property>
<property name="maxStatements">50</property>
<property name="preferredTestQuery">SELECT 1;</property>
<property name="acquireRetryAttempts">5</property>
<property name="acquireRetryDelay">200</property>
<property name="maxIdleTime">30</property>
</default-config>
</c3p0-config>
but if you run, ORM takes the jdbc connection but not C3p0 connection pool 'cause we should add these properties in hibernate.cfg.xml
<property name="hibernate.c3p0.validate">true</property>
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
now everything works fine(At least it worked fine for me) and the issue is solved.
check the following for references.
http://www.mchange.com/projects/c3p0/index.html#configuring_connection_testing
https://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool
I hope this solves your problem.